This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.


1. Introduction:

Explain why you chose this topic

In this final project, analyzing the urbanization in east asia in the years of 2000 and 2010 is the main goal. Reasons of considering this issue are the following:

  • Both of team members are originally from East Asia and have been experiencing the change of the East Asia in urbanization. As from the East Asia, we want to provide people with a clear view on the magnitude of changes that can happen in only one decade and challenges people to think about the impact on the following years. Quantifying and visualizing this whole process is very interesting for both of us.

  • In the meantime, we are also very interested in social science and critical issues in the society like urbanization, economic increasing, population increasing, environment polution and their paired relationships. Analyzing the visualizing these problems are very promising as well.

  • Making societies to shift from a rural nature to a urban nature on a sustainable way is an interesting and important research topic. Although the growth of urban areas provides opportunities for the poor, urban expansion can also aggravate inequality in access to services, employment, and housing. The spatial expansion of a city directly affects the poor in its path.

  • One of team members has the background in economic, so it is beneficial for us to conduct econ-related problems.

The questions you are interested in studying.

  • Looking at the distribution of East Asia’s population in urban and non-urban. This will allow us to predict whether the region will likely face urbanization within next decades.

  • Looking at the urbanization situation in the biggest developing country around the world

  • Detecting the potential relationship between urbanization expansion and urban population growth.

  • Finding out the distribution of the rate of urban population change, urban land change, and urban population density change in a decade

  • Finding out the relationship between administrative boundary types and urban population, urban land and urban population density.

Include a brief description of how you found the data

At the very begainning, we googled the dataset by key words urbanization dataset. It poped out the results mostly from UN website and there are some problems for these datasets.

  • Some of them are imcomplete and nonaggregated.

  • One of datasets does not include some very interesting variables.

  • Another important reason is these datasets do not include regions that we are interested in.

Finally, we found the dataset from the webiste of the authoritative organization WorldBank. It has following advantages:

  • The dataset is complete and readable. But we still need to clean and process the data to the format and structure that are suitable for our visualization process.

  • The dataset includes some very interesting features (numerical and categorical) which will allow us to implement various visulization graphs and find out different results.

  • The dataset accurately focus on the East Asia region which is exactly what we want.

Clear instructions on where the reader can find the data

  • Follow the attached link to find the dataset from World Bank: https://puma.worldbank.org/intro/index.php/downloads/20

  • There are many datasets showed in the website categorized by regions and countries.

  • The dataset we used is the Urban Expansion 2000-2010 - Overview

  • The dataset includes two Excel files. One about each country as a whole and one about the 869 cities.


2. Team Info and Contribution


3. Analysis of Data Quality

Process data

  • The data is relatively tidy with few missing data. Also we get extra data of longitude and latitude using packages in R.
library(ggplot2)
library(readxl)
library(dplyr)
data1 = read_excel("data/Changes in Urban Land, Population and Density by Country.xlsx", sheet = 'Countries', skip=2)
data1 = data1[-c(1,20,21,22),-16]
data1$Country[c(4,7,13,15)] = c("North Korea", "Laos", "South Korea", "Taiwan")
country_name = data1$Country
data2 = read_excel("data/Urban Areas with Populations Greater Than 100,000 People.xlsx", sheet = 'Urban_Areas_by_pop', skip = 2)
data2 = data2 %>% na.omit()
data2 = data2[-1]
temp = factor(data2$Country)
levels(temp) = country_name
data2$Country = as.character(temp)
city_name = gsub(" urban area", "", data2$`Urban Area Name`)
city_name = gsub("'", " ", city_name)
city_name = paste(city_name, data2$Country, sep=", ")
#coord = geocode(city_name, messaging = F)
#write.csv(coord, file = "EDA_Project/data/coord.csv", row.names=FALSE)
coord = read.csv("data/coord.csv")
data2$lon = coord$lon
data2$lat = coord$lat

Variable 1: Country

g=ggplot(data2,aes(Country))+
  geom_histogram(fill="skyblue", color="white", stat = "count")+
  ggtitle("Histogram of number of urban areas in each country")+
  theme(axis.text.x = element_text(angle = 30, hjust = 1))
g

  • The histogram of the catagorical variable Country shows the number of urban areas that appear in the data.The variable Country is very important for our analysis in project. The plot provides us the distribution of urban areas and a general idea of the scale of population and land area. It is clear that China dominates other Eastern Asian countries in the number of urban areas by a large number of urban areas. In terms of data quality, we need to realize that the data cannot represent East Asian countries as identical entity and we need to analyze by countries with more focus on China specifically. In order to visualize the number of urban areas of other countries more efficiently with reasonable scaling, we exclude China in the next histogram.
no_china=data2[which(data2$Country!="China"),]
g=ggplot(no_china,aes(Country))+
  geom_histogram(fill="skyblue", color="white", stat = "count")+
  ggtitle("Histogram of number of urban areas without China")+
  theme(axis.text.x = element_text(angle = 30, hjust = 1))
g

  • In this histogram, Indonesia takes the second place and Japan takes the third in the number of urban areas. They also dominate the rest of countries but with much fewer amount of urban areas compared to China. Some of the countries like Brunei may only have a few urban area in our dataset because such countries are so small in terms of urban land size and urban population. In this case, such countries will not impact much about our analysis of East Asian urbanizaiton in general.

Variable 2: Average annual rate of increase in urban land 2000 - 2010 (%)

g=ggplot(data2,aes(`Average annual rate of increase in urban land 2000 - 2010 (%)`))+
  geom_histogram(fill="skyblue", color="white")+
  ggtitle("Histogram of Average annual rate of increase in urban land 2000 - 2010")
g

ggplot(data2, aes(x="",y=`Average annual rate of increase in urban land 2000 - 2010 (%)`))+
geom_boxplot(outlier.colour="red", outlier.shape=16,
             outlier.size=2, notch=T)

  • The histogram shows that from 2000 to 2010 in East Asia, urban land size increases with urbanization. Most of urban areas do have their urban land increase at the average annual rate from 0% to 5%, preferably 0%. Few urban areas increase beyond annual rate of 10%. But no urban area shrinks during urbanization. This indicates that the expanding urban areas is necessary for urbanization process even though at relatively low rate. In terms of data quality, this variable is generally good for our analysis even with few outliers. The boxplot shows that all outliers are in the larger side of the variable values. We can take those outliers out and analyze them individually to see the reason why the rate is so high.

Variable 3: Average annual rate of change of urban population (%)

g=ggplot(data2,aes(`Average annual rate of change of urban population (%)`))+
  geom_histogram(fill="skyblue", color="white")+
  ggtitle("Histogram of Average annual rate of increase in urban population")
g

ggplot(data2, aes(x="",y=`Average annual rate of change of urban population (%)`))+
geom_boxplot(outlier.colour="red", outlier.shape=16,
             outlier.size=2, notch=T)

  • This histogram shows that from 2000 to 2010, most of the urban areas in East Asia have increased in urban population size while few have decreased in urban population size. The boxplot shows that there are some outliers on both sides but the outliers seem reasonable since some urban areas grow much faster than others in population. The range of the rate of change of urban population is acceptable and the distribution is rougly normal and this variable is good to use in the analysis.

Variable 4: Urban expansion per additional urban inhabitant (sq. m./ person)

g=ggplot(data2,aes(`Urban expansion per additional urban inhabitant (sq. m./ person)`))+
  geom_histogram(fill="skyblue", color="white")+
  ggtitle("Histogram of Urban expansion per additional urban inhabitant (Original)")
g

ggplot(data2, aes(x="",y=`Urban expansion per additional urban inhabitant (sq. m./ person)`))+
geom_boxplot(outlier.colour="red", outlier.shape=16,
             outlier.size=2, notch=T)

  • Both the histogram and the boxplot of Urban expansion per additional urban inhabitant (sq. m./ person) shows that there are several outliers in this variable. In addition, there is one outlier with extremely negative value that makes the two plots look strange. Also, there are some other outliers with smaller deviation from the most of the data values and we can exclude them to see a clearer distribution of this variable.
most = data2[data2$`Urban expansion per additional urban inhabitant (sq. m./ person)`>-1e+03&data2$`Urban expansion per additional urban inhabitant (sq. m./ person)`<2000,]
g=ggplot(most,aes(`Urban expansion per additional urban inhabitant (sq. m./ person)`))+
  geom_histogram(fill="skyblue", color="white",binwidth = 50)+
  ggtitle("Histogram of Urban expansion per additional urban inhabitant (modified)")
g

  • In this histogram, with elimination of values below -1000 and beyond 2000, we get a much nicer visualization of the distribution of Urban expansion per additional urban inhabitant from 2000 to 2010. It shows that most of the urban areas in East Asia have approximately 0 to 300 urban expansion per additional urban inhabitant. There are still some urban areas have negative value and this corresponds to the two histograms above which show that in those urban areas, their land sizes increase while their population decrease.

4. Executive Summary

figure 1

figure 1

figure 2

figure 2

figure 3

figure 3

5. Main Analysis

Introduction

Urbanization is the most common phenomenon for the modern societies. The nature of society is shifting from a dependency of rural area to a more and more urban area. However, there are various issues accompanying with the significant urbanization, such as over-population, pollution, economic effects and etc. Therefore, detecting a sustainable and equitable path of urbanization is one of the most critical problems for social scientists.

In our project, visulizations are based on the urbanizaed situations in East Asia between 2000 and 2010 collected by the World Bank. Therefore, through our project, it is easy for us to get a clear view on the magnitude of changes that happened in one decode. What is more, it can also facilitate viewers to think abou the impacts on the following yeas.

Our data is from the 869 urban areas in the region with populations over 100,000 in 2010

Map

In the process of creating the interactive maps, we include several variables, numerical and categorical. At the first select, the viewer can choose the Year and Boundary can also be specified. At the end, the user can also choose the measure which can be urban population and urban land to look at the distribution across areas in the map. Importantly, the radius of cicles in the map are determined by the measure that the use chose and the circles are colored by the population density. Throught the map, the view can have a comprehensive understanding of various variables across urban areas in the actual positions. When the viewer puts the cursor on the actual points, he can get the area name for that specific point.

Map1

Map1

  • Finding1 There is a significant increase of population in this decade, about 200 million people and this would be the world’s sixth-largest population if we consider it for any single country. In details, there were 580 million people living in these 869 cities and in just ten years, this number jumps to 780 million. It is necessary for cities to consider the housing and infrastructure issues with this amount of people of the move.

  • Finding2 There are some giant megacities has emerged during these ten years. There are 8 megacities with more than 10 million people in 2010.

  • Finding3 China is the dominating country in this urbanization process since the majority of urban areas are from China and they all have significantly increase in terms of land area and population. For example, the Pearl River Delta in China has overtaken Tokyo as the world’s largest urban area considering land area and population.

Map2

Map2

Map3 * Finding4 The size and population of urban areas are highly related to the boundary type. As we can get from the map, if we fix a size measure and adjust to the boundary type, the appearance of measures across urban area are greatly different.

Data Explorer

Explorer

Explorer

In this tab, we include a DT table into our shiny app, where provides the most direct ways for user to look at the data and get a sense of whole dataset. There are various functionalities in this table:

  • search bar at the top of the table to search by country, boundary type or urban areas and even all of them

  • selection slider below all the column names to select rows by the range of variables

  • extension button the table information may be hidden by the size of pages and the user can look at the whole data of each row by clicking on the greeen plus button

The Data Explorer table provides a way for views who like playing with raw data and get a sense of dataset.

Slope Plots

Through the slope plots, we can get a closer look of the absolute changes of various measure across cities, such as population, land area and population density. In the left side of the slope plot, measure selected by users of 2000 are showing there. In the right side of the slope plot, the paired variable of 2010 is showing there. We include Land area, Population Density and Population into our measure selection. Additionally, the color of lines can be determined by Country or Boundary Type. Depending on the different groups, measure variables can have a variaty of performances across areas. At the mean time, the change rate of each variable for every area can also be showed through the slope plots.

Slope2

Slope2

  • Finding1 If we select the Population measure, we can see urban population in 2000 on the left side and in 2010 on the right. It can also varify our one of findings from the Map that the Pearl River Delta Area in China has become the largest urban area in East Asia and even in the world. What is more, in terms of population, cities can be seperated into three groups, Pearl River Delta area and Tokyo area are the most giant megacities in East Asia. Other cities like Jakarta area from Indonesia, Seoul area from Korea, Manila area from Philippnes, Osaka area from Japan and Beijing area from China can be considered as second groups. The population of rest of urban areas are within a relativly similar range.
Slope3

Slope3

  • Finding2 When we select the Population Density measure, we can conclude that the population density of most urban area have increased within these ten years and the over-population problem is even worse in 2010 than in 2000. However, as the one of the most crowed area in the world, Hongkong has been dealing with over-population problem for a century. Fortunely, there is a slightly decrease of population density in HongKong from 33.23 to 32.13.

  • Finding3 The crowded area problem is more sever in other Asian countries than China which has a large amount of urban areas. For example, for countries like Indonesia, Vietnam and Philippnes, there are several urban areas with population density larger than 20. On the countrary, for most urban areas in China, population densities are pretty low. Therefore, for areas with high population density, the housing shortage may be a critical issue. However, low population density does not mean over-population is not a big issue for urban areas since overcoming the over-population problem and reasonably make the resource arrangement is one of the most difficult tasks for local governments.

Slope1

Slope1

  • Finding4 Considering the land areas, large famous urban areas jump into our view such as Pearl River Delta , Tokyo, Shanghai and Beijing. We can also notice that there is still a huge increase of land areas for cities in China but it is not the situation in Tokyo. One of the reasons behind this phenomenon possibly be the limitation of country size of Japan and the tremendous land areas of China. Another reason could be the actual economic situation of these areas since Pearl River Delta, Shanghai and Beijing are the most advanced areas in China with the largest economic effects on the whole country. Therefore, it is common for these three cities to attract more people to work and live there and enlarge the whole area.
Slope4

Slope4

  • Finding5 If we adjust the comparision measure and Boundary Type, we can easily detect that Contained boundary type dominates the whole dataset across comparsion measure. Specifically, urban areas with high population, population density or land area are mostly categorized into contained boundary type.

Heatmaps

In order to compare the degree of difference of all the numerical features, we included a Heatmap in our shiny app so we can look at some statistic summaries of the numerical features in terms of boundary type. The rows of our heatmaps are Countries and the columns of the heatmaps are following statistical summary of each variable: mean, median, sd and Boundary Type. The color of left three columns is determined by the value of each cells and the color of right three columns which are Boundary Type is determined by the measure that the viewer chose at the right top of the page

While creating the data matrix, we need group the variable we need by country and summrise the variable into metrics that we ask. At the end, we need to concatenate this dataframe with boundary type datafram into the final datafrome, and then we change the datatype into matrix and put the matrix into the heatmap.2 function to draw the heatmap. Importantly, in order to label each row with country name, we have to clarify the row names for the dataframe and the matrix will keep this attribute.

Heatmap1

Heatmap1

  • Finding1 When we look at the urban land no matter in 2000 or 2010, we can find that some countries have outstanding median and mean values such as Singapore and Mongolia, which is normal, since for these two countries, they only have one major urban area respectively. Although other countries like China has more urban areas, their land areas are not consistenly large.
Heatmap2

Heatmap2

  • Finding2 If we take a look at the Urban Population paired variables in 2000 and 2010, the comparasion follows the same pattern as the Finding1. Some countries have higher mean and median values such as Singapore, Mongolia plus Cambodia than rest of countries. Interestingly, for some countries like North Korean, Papua New Guinea, Laos, Brunei and Timor-Leste, the smaller mean and median value may be decided by the total population of the whole coutry or some possible political reasons.
Heatmap3

Heatmap3

  • Finding3 The distribution of population density is even more interesting in terms of above two Findings than looking at alone. Take North Korean as an example, it has a high population density in both 2000 and 2010 but small values in metrics of Urban Population and urban land. It reflects that the population density issue is more critical issue for the centual government in countries with few urban areas than other countries. In order to verify the conclusion, we can look back to our Slope Plot and we cannot find the areas of North Korea from the top of Slope Plot. From the social scientist perspective, we may reasonably hypotheis that countries like North Korea may not have suffucient experience dealing with high population density issue.

Other Plots

Dot Plot

In order to show the distribution of increase rate of population, we need to create a new columns for the existed dataframe by using mutate function from dplyr through diving the population by the population in 2000 for each area. What is more, we need to color the dots. At the begainning, we tried to color each dot by the population in 2010, unfortunately, there is no identical number of population for each area, so the color is meaningless. Then, we started to factor the dots into different groups by the number of population in 2010. Finally, we found that 500K, 1 million, 5 million are the most appropriate break points to distinct different dots. We also verify our grouping stategy through a scientific research about defining the size of cities from a institute in China. The color schemes of the land dot plot and population density dot plot are also following the same strategy which has proved very meaningful and effective to detect rich information through dot plots.

Dotplot2

Dotplot2

  • Finding1 When we choose Land as measure, we can look at the rate of increase of land for each urban area colored by the land area. In order to make this plot, we mutate two new columns called land_increase and land_factor, which representes the increase of land of each urban area and factorize the land area into 5 levels. Then, the dot plot can be created by counting the number of each increase rate and color the dots by the land_factor levels. Like our expectations, for existed urban areas with large land, it is not common that they will increase a lot of the land area, but there probably a huge increase for small land urban area. Interestingly, we found that there are several huge land areas having significantly increase in the land. Importantly, growth may lead to economic opportunities. However, this situation also force policy makers to think the design of cities carefully since the arrangement of infrastructure has already been a crucial decision. While considering the particular situation for each city, they have their own challenges and opportunities in different ways.
Dotplot1

Dotplot1

  • Finding2 When we consider Population as measure, we can get a clear view about the growth of urban population. The first view we can get is many cities have seen an enormous growth in their population between 2000 and 2010. There are definitely outliers if we consider the growth in a certain range since we can detect that there are several areas having population growth rate more than 150%.
Dotplot3

Dotplot3

  • Finding3 If we look at the Population Density, there are both large increase and decline. Impotantly, if we take a look at the Data Explorer part, we can find that majority of Chinese cities have a density decline. in our opinions, this could be influenced by the phenomenon of ‘Ghost cities’ and rising incomes. Furthermore, we can focus on the areas with high density increase and we find that low income countries have a comparatively high growth since people usually migrate freely.

Histogram

Histogram3

Histogram3

  • Finding1 histogram of the catagorical variable Country shows the number of urban areas that appear in the data.The variable Country is very important for our analysis in project. Since different countries vary in aspects such as population, land area, economic development levels, the levels of their urbanization are also different from each other. The plot provides us the distribution of urban areas and a general idea of the scale of population and land area. It is clear that China dominates other Eastern Asian countries in the number of urban areas by a large number of urban areas. In order to visualize the number of urban areas of other countries more efficiently with reasonable scaling, we exclude China in the next histogram.
Histogram1

Histogram1

  • Finding2 histogram shows that from 2000 to 2010 in East Asia, urban land size increases with urbanization. Most of urban areas do have their urban land increase at the average annual rate from 0% to 5%, preferably 0%. Few urban areas increase beyond annual rate of 10%. But no urban area shrinks during urbanization. This indicates that the expanding urban areas is necessary for urbanization process even though at relatively low rate.
Histogram2

Histogram2

  • Finding3 histogram shows that from 2000 to 2010, most of the urban areas in East Asia have increased in urban population size while few have decreased in urban population size. In common sense, undergoing urbanization should have increase in its population. However, ompared to previous histogram of average rate of increase in urban land that shows that urban land size increases in urbanization, this histogram indicates that with few urban areas decrease in urban lan size, expansion of urban population is not necessary but common in urbanization.

6. Conclusion

Code link: https://github.com/zangcc0474/EDA_Final.git

Shiny visualization link: https://meka.shinyapps.io/eda_project/#

LS0tCnRpdGxlOiAiRWFzdCBBc2lhIFVyYmFuaXphdGlvbiIKYXV0aG9yOiAiS2UgTWEta20zMTk0IHwgQ2hlbmNoYW8gWmFuZy1jejI0MzEiCmRhdGU6ICJBcHJpbCAyMCwgMjAxNyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgoqKioKCiMjIDEuIEludHJvZHVjdGlvbjoKIyMjIyBFeHBsYWluIHdoeSB5b3UgY2hvc2UgdGhpcyB0b3BpYwoKSW4gdGhpcyBmaW5hbCBwcm9qZWN0LCBhbmFseXppbmcgdGhlIHVyYmFuaXphdGlvbiBpbiBlYXN0IGFzaWEgaW4gdGhlIHllYXJzIG9mIDIwMDAgYW5kIDIwMTAgaXMgdGhlIG1haW4gZ29hbC4gUmVhc29ucyBvZiBjb25zaWRlcmluZyB0aGlzIGlzc3VlIGFyZSB0aGUgZm9sbG93aW5nOgoKKiBCb3RoIG9mIHRlYW0gbWVtYmVycyBhcmUgb3JpZ2luYWxseSBmcm9tIEVhc3QgQXNpYSBhbmQgaGF2ZSBiZWVuIGV4cGVyaWVuY2luZyB0aGUgY2hhbmdlIG9mIHRoZSBFYXN0IEFzaWEgaW4gdXJiYW5pemF0aW9uLiBBcyBmcm9tIHRoZSBFYXN0IEFzaWEsIHdlIHdhbnQgdG8gcHJvdmlkZSBwZW9wbGUgd2l0aCBhIGNsZWFyIHZpZXcgb24gdGhlIG1hZ25pdHVkZSBvZiBjaGFuZ2VzIHRoYXQgY2FuIGhhcHBlbiBpbiBvbmx5IG9uZSBkZWNhZGUgYW5kIGNoYWxsZW5nZXMgcGVvcGxlIHRvIHRoaW5rIGFib3V0IHRoZSBpbXBhY3Qgb24gdGhlIGZvbGxvd2luZyB5ZWFycy4gIFF1YW50aWZ5aW5nIGFuZCB2aXN1YWxpemluZyB0aGlzIHdob2xlIHByb2Nlc3MgaXMgdmVyeSBpbnRlcmVzdGluZyBmb3IgYm90aCBvZiB1cy4KCiogSW4gdGhlIG1lYW50aW1lLCB3ZSBhcmUgYWxzbyB2ZXJ5IGludGVyZXN0ZWQgaW4gc29jaWFsIHNjaWVuY2UgYW5kIGNyaXRpY2FsIGlzc3VlcyBpbiB0aGUgc29jaWV0eSBsaWtlIHVyYmFuaXphdGlvbiwgZWNvbm9taWMgaW5jcmVhc2luZywgcG9wdWxhdGlvbiBpbmNyZWFzaW5nLCBlbnZpcm9ubWVudCBwb2x1dGlvbiBhbmQgdGhlaXIgcGFpcmVkIHJlbGF0aW9uc2hpcHMuIEFuYWx5emluZyB0aGUgdmlzdWFsaXppbmcgdGhlc2UgcHJvYmxlbXMgYXJlIHZlcnkgcHJvbWlzaW5nIGFzIHdlbGwuCgoqIE1ha2luZyBzb2NpZXRpZXMgdG8gc2hpZnQgZnJvbSBhIHJ1cmFsIG5hdHVyZSB0byBhIHVyYmFuIG5hdHVyZSBvbiBhIHN1c3RhaW5hYmxlIHdheSBpcyBhbiBpbnRlcmVzdGluZyBhbmQgaW1wb3J0YW50IHJlc2VhcmNoIHRvcGljLiBBbHRob3VnaCB0aGUgZ3Jvd3RoIG9mIHVyYmFuIGFyZWFzIHByb3ZpZGVzIG9wcG9ydHVuaXRpZXMgZm9yIHRoZSBwb29yLCB1cmJhbiBleHBhbnNpb24gY2FuIGFsc28gYWdncmF2YXRlIGluZXF1YWxpdHkgaW4gYWNjZXNzIHRvIHNlcnZpY2VzLCBlbXBsb3ltZW50LCBhbmQgaG91c2luZy4gVGhlIHNwYXRpYWwgZXhwYW5zaW9uIG9mIGEgY2l0eSBkaXJlY3RseSBhZmZlY3RzIHRoZSBwb29yIGluIGl0cyBwYXRoLiAKCiogT25lIG9mIHRlYW0gbWVtYmVycyBoYXMgdGhlIGJhY2tncm91bmQgaW4gZWNvbm9taWMsIHNvIGl0IGlzIGJlbmVmaWNpYWwgZm9yIHVzIHRvIGNvbmR1Y3QgZWNvbi1yZWxhdGVkIHByb2JsZW1zLgoKIyMjIyBUaGUgcXVlc3Rpb25zIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBzdHVkeWluZy4KCiogTG9va2luZyBhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIEVhc3QgQXNpYSdzIHBvcHVsYXRpb24gaW4gdXJiYW4gYW5kIG5vbi11cmJhbi4gVGhpcyB3aWxsIGFsbG93IHVzIHRvIHByZWRpY3Qgd2hldGhlciB0aGUgcmVnaW9uIHdpbGwgbGlrZWx5IGZhY2UgdXJiYW5pemF0aW9uIHdpdGhpbiBuZXh0IGRlY2FkZXMuCgoqIExvb2tpbmcgYXQgdGhlIHVyYmFuaXphdGlvbiBzaXR1YXRpb24gaW4gdGhlIGJpZ2dlc3QgZGV2ZWxvcGluZyBjb3VudHJ5IGFyb3VuZCB0aGUgd29ybGQKCiogRGV0ZWN0aW5nIHRoZSBwb3RlbnRpYWwgcmVsYXRpb25zaGlwIGJldHdlZW4gdXJiYW5pemF0aW9uIGV4cGFuc2lvbiBhbmQgdXJiYW4gcG9wdWxhdGlvbiBncm93dGguCgoqIEZpbmRpbmcgb3V0IHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHJhdGUgb2YgdXJiYW4gcG9wdWxhdGlvbiBjaGFuZ2UsIHVyYmFuIGxhbmQgY2hhbmdlLCBhbmQgdXJiYW4gcG9wdWxhdGlvbiBkZW5zaXR5IGNoYW5nZSBpbiBhIGRlY2FkZQoKKiBGaW5kaW5nIG91dCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYWRtaW5pc3RyYXRpdmUgYm91bmRhcnkgdHlwZXMgYW5kIHVyYmFuIHBvcHVsYXRpb24sIHVyYmFuIGxhbmQgYW5kIHVyYmFuIHBvcHVsYXRpb24gZGVuc2l0eS4KCgojIyMjIEluY2x1ZGUgYSBicmllZiBkZXNjcmlwdGlvbiBvZiBob3cgeW91IGZvdW5kIHRoZSBkYXRhCgpBdCB0aGUgdmVyeSBiZWdhaW5uaW5nLCB3ZSBnb29nbGVkIHRoZSBkYXRhc2V0IGJ5IGtleSB3b3JkcyBgdXJiYW5pemF0aW9uIGRhdGFzZXRgLiBJdCBwb3BlZCBvdXQgdGhlIHJlc3VsdHMgbW9zdGx5IGZyb20gYFVOYCB3ZWJzaXRlIGFuZCB0aGVyZSBhcmUgc29tZSBwcm9ibGVtcyBmb3IgdGhlc2UgZGF0YXNldHMuIAoKKiBTb21lIG9mIHRoZW0gYXJlIGltY29tcGxldGUgYW5kIG5vbmFnZ3JlZ2F0ZWQuCgoqIE9uZSBvZiBkYXRhc2V0cyBkb2VzIG5vdCBpbmNsdWRlIHNvbWUgdmVyeSBpbnRlcmVzdGluZyB2YXJpYWJsZXMuCgoqIEFub3RoZXIgaW1wb3J0YW50IHJlYXNvbiBpcyB0aGVzZSBkYXRhc2V0cyBkbyBub3QgaW5jbHVkZSByZWdpb25zIHRoYXQgd2UgYXJlIGludGVyZXN0ZWQgaW4uCgpGaW5hbGx5LCB3ZSBmb3VuZCB0aGUgZGF0YXNldCBmcm9tIHRoZSB3ZWJpc3RlIG9mIHRoZSBhdXRob3JpdGF0aXZlIG9yZ2FuaXphdGlvbiBgV29ybGRCYW5rYC4gSXQgaGFzIGZvbGxvd2luZyBhZHZhbnRhZ2VzOgoKKiBUaGUgZGF0YXNldCBpcyBjb21wbGV0ZSBhbmQgcmVhZGFibGUuIEJ1dCB3ZSBzdGlsbCBuZWVkIHRvIGNsZWFuIGFuZCBwcm9jZXNzIHRoZSBkYXRhIHRvIHRoZSBmb3JtYXQgYW5kIHN0cnVjdHVyZSB0aGF0IGFyZSBzdWl0YWJsZSBmb3Igb3VyIHZpc3VhbGl6YXRpb24gcHJvY2Vzcy4KCiogVGhlIGRhdGFzZXQgaW5jbHVkZXMgc29tZSB2ZXJ5IGludGVyZXN0aW5nIGZlYXR1cmVzIChudW1lcmljYWwgYW5kIGNhdGVnb3JpY2FsKSB3aGljaCB3aWxsIGFsbG93IHVzIHRvIGltcGxlbWVudCB2YXJpb3VzIHZpc3VsaXphdGlvbiBncmFwaHMgYW5kIGZpbmQgb3V0IGRpZmZlcmVudCByZXN1bHRzLgoKKiBUaGUgZGF0YXNldCBhY2N1cmF0ZWx5IGZvY3VzIG9uIHRoZSBFYXN0IEFzaWEgcmVnaW9uIHdoaWNoIGlzIGV4YWN0bHkgd2hhdCB3ZSB3YW50LgoKIyMjIyBDbGVhciBpbnN0cnVjdGlvbnMgb24gd2hlcmUgdGhlIHJlYWRlciBjYW4gZmluZCB0aGUgZGF0YQoKICAqIEZvbGxvdyB0aGUgYXR0YWNoZWQgbGluayB0byBmaW5kIHRoZSBkYXRhc2V0IGZyb20gYFdvcmxkIEJhbmtgOiBodHRwczovL3B1bWEud29ybGRiYW5rLm9yZy9pbnRyby9pbmRleC5waHAvZG93bmxvYWRzLzIwCiAgCiAgKiBUaGVyZSBhcmUgbWFueSBkYXRhc2V0cyBzaG93ZWQgaW4gdGhlIHdlYnNpdGUgY2F0ZWdvcml6ZWQgYnkgcmVnaW9ucyBhbmQgY291bnRyaWVzLgogIAogICogVGhlIGRhdGFzZXQgd2UgdXNlZCBpcyB0aGUgYFVyYmFuIEV4cGFuc2lvbiAyMDAwLTIwMTAgLSBPdmVydmlld2AKICAKICAqIFRoZSBkYXRhc2V0IGluY2x1ZGVzIHR3byBFeGNlbCBmaWxlcy4gT25lIGFib3V0IGVhY2ggY291bnRyeSBhcyBhIHdob2xlIGFuZCBvbmUgYWJvdXQgdGhlIDg2OSBjaXRpZXMuIAoKKioqCiMjIDIuIFRlYW0gSW5mbyBhbmQgQ29udHJpYnV0aW9uCgoqICoqVGVhbSBtZW1iZXJzOioqIAogICAgKiBLZSBNYSAtIFVOSToga20zMTk0CiAgICAqIENoZW5jaGFvIFphbmcgLSBVTkk6IGN6MjQzMQoqICoqQ29udHJpYnV0aW9ucyoqCiAgICAqIEtlIGFuZCBDaGVuY2hhbyB3aWxsIGNsZWFuIGFuZCBwcm9jZXNzIHRoZSBkYXRhIHRvIHRoZSBkZXNpcmVkIGZvcm1hdCBhbmQgZG8gdGhlIHZpc3VhbGl6YXRpb24gdG9nZXRoZXIuIFNwZWNpZmljYWxseSwgS2Ugd2lsbCBmb2N1cyBtb3JlIG9uIGdyYXBoaW5nIHRoZSBtYXBzIGZvciB0aGUgY291bnRyaWVzIHVzaW5nIHBhY2thZ2VzIGxpa2UgYGxlYWZsZXRgIGFuZCBgc2hpbnlgLiBDaGVuY2hhbyB3aWxsIGZvY3VzIG1vcmUgb24gdGhlIGFuYWx5dGljYWwgZ3JhcGhpbmcgdXNpbmcgcGFja2FnZXMgbGlrZSBgZ2dwbG90YC4gRmluYWxseSwgd2Ugd3JvdGUgdGhlIHJlcG9ydCB0b2dldGhlciBidXQgd2lsbCBmb2N1cyBtb3JlIG9uIHRoZSBwYXJ0cyBlYWNoIHNoYWxsIGRvIGluIHZpc3VhbGl6YXRpb24uCgoqKioKIyMgMy4gQW5hbHlzaXMgb2YgRGF0YSBRdWFsaXR5CiMjIyBQcm9jZXNzIGRhdGEKKiBUaGUgZGF0YSBpcyByZWxhdGl2ZWx5IHRpZHkgd2l0aCBmZXcgbWlzc2luZyBkYXRhLiBBbHNvIHdlIGdldCBleHRyYSBkYXRhIG9mIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUgdXNpbmcgcGFja2FnZXMgaW4gUi4KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoZHBseXIpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRhdGExID0gcmVhZF9leGNlbCgiZGF0YS9DaGFuZ2VzIGluIFVyYmFuIExhbmQsIFBvcHVsYXRpb24gYW5kIERlbnNpdHkgYnkgQ291bnRyeS54bHN4Iiwgc2hlZXQgPSAnQ291bnRyaWVzJywgc2tpcD0yKQpkYXRhMSA9IGRhdGExWy1jKDEsMjAsMjEsMjIpLC0xNl0KZGF0YTEkQ291bnRyeVtjKDQsNywxMywxNSldID0gYygiTm9ydGggS29yZWEiLCAiTGFvcyIsICJTb3V0aCBLb3JlYSIsICJUYWl3YW4iKQpjb3VudHJ5X25hbWUgPSBkYXRhMSRDb3VudHJ5CmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRhdGEyID0gcmVhZF9leGNlbCgiZGF0YS9VcmJhbiBBcmVhcyB3aXRoIFBvcHVsYXRpb25zIEdyZWF0ZXIgVGhhbiAxMDAsMDAwIFBlb3BsZS54bHN4Iiwgc2hlZXQgPSAnVXJiYW5fQXJlYXNfYnlfcG9wJywgc2tpcCA9IDIpCmRhdGEyID0gZGF0YTIgJT4lIG5hLm9taXQoKQpkYXRhMiA9IGRhdGEyWy0xXQp0ZW1wID0gZmFjdG9yKGRhdGEyJENvdW50cnkpCmxldmVscyh0ZW1wKSA9IGNvdW50cnlfbmFtZQpkYXRhMiRDb3VudHJ5ID0gYXMuY2hhcmFjdGVyKHRlbXApCmBgYAoKYGBge3J9CmNpdHlfbmFtZSA9IGdzdWIoIiB1cmJhbiBhcmVhIiwgIiIsIGRhdGEyJGBVcmJhbiBBcmVhIE5hbWVgKQpjaXR5X25hbWUgPSBnc3ViKCInIiwgIiAiLCBjaXR5X25hbWUpCmNpdHlfbmFtZSA9IHBhc3RlKGNpdHlfbmFtZSwgZGF0YTIkQ291bnRyeSwgc2VwPSIsICIpCiNjb29yZCA9IGdlb2NvZGUoY2l0eV9uYW1lLCBtZXNzYWdpbmcgPSBGKQojd3JpdGUuY3N2KGNvb3JkLCBmaWxlID0gIkVEQV9Qcm9qZWN0L2RhdGEvY29vcmQuY3N2Iiwgcm93Lm5hbWVzPUZBTFNFKQpjb29yZCA9IHJlYWQuY3N2KCJkYXRhL2Nvb3JkLmNzdiIpCgpkYXRhMiRsb24gPSBjb29yZCRsb24KZGF0YTIkbGF0ID0gY29vcmQkbGF0CmBgYAoKIyMjIyBWYXJpYWJsZSAxOiBgQ291bnRyeWAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnPWdncGxvdChkYXRhMixhZXMoQ291bnRyeSkpKwogIGdlb21faGlzdG9ncmFtKGZpbGw9InNreWJsdWUiLCBjb2xvcj0id2hpdGUiLCBzdGF0ID0gImNvdW50IikrCiAgZ2d0aXRsZSgiSGlzdG9ncmFtIG9mIG51bWJlciBvZiB1cmJhbiBhcmVhcyBpbiBlYWNoIGNvdW50cnkiKSsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpKQpnCmBgYAoKKiBUaGUgaGlzdG9ncmFtIG9mIHRoZSBjYXRhZ29yaWNhbCB2YXJpYWJsZSBgQ291bnRyeWAgc2hvd3MgdGhlIG51bWJlciBvZiB1cmJhbiBhcmVhcyB0aGF0IGFwcGVhciBpbiB0aGUgZGF0YS5UaGUgdmFyaWFibGUgYENvdW50cnlgIGlzIHZlcnkgaW1wb3J0YW50IGZvciBvdXIgYW5hbHlzaXMgaW4gcHJvamVjdC4gVGhlIHBsb3QgcHJvdmlkZXMgdXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiB1cmJhbiBhcmVhcyBhbmQgYSBnZW5lcmFsIGlkZWEgb2YgdGhlIHNjYWxlIG9mIF9wb3B1bGF0aW9uXyBhbmQgX2xhbmQgYXJlYV8uIEl0IGlzIGNsZWFyIHRoYXQgYENoaW5hYCBkb21pbmF0ZXMgb3RoZXIgRWFzdGVybiBBc2lhbiBjb3VudHJpZXMgaW4gdGhlIG51bWJlciBvZiB1cmJhbiBhcmVhcyBieSBhIGxhcmdlIG51bWJlciBvZiB1cmJhbiBhcmVhcy4gSW4gdGVybXMgb2YgZGF0YSBxdWFsaXR5LCB3ZSBuZWVkIHRvIHJlYWxpemUgdGhhdCB0aGUgZGF0YSBjYW5ub3QgcmVwcmVzZW50IEVhc3QgQXNpYW4gY291bnRyaWVzIGFzIGlkZW50aWNhbCBlbnRpdHkgYW5kIHdlIG5lZWQgdG8gYW5hbHl6ZSBieSBjb3VudHJpZXMgd2l0aCBtb3JlIGZvY3VzIG9uIENoaW5hIHNwZWNpZmljYWxseS4gSW4gb3JkZXIgdG8gdmlzdWFsaXplIHRoZSBudW1iZXIgb2YgdXJiYW4gYXJlYXMgb2Ygb3RoZXIgY291bnRyaWVzIG1vcmUgZWZmaWNpZW50bHkgd2l0aCByZWFzb25hYmxlIHNjYWxpbmcsIHdlIGV4Y2x1ZGUgYENoaW5hYCBpbiB0aGUgbmV4dCBoaXN0b2dyYW0uCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kbm9fY2hpbmE9ZGF0YTJbd2hpY2goZGF0YTIkQ291bnRyeSE9IkNoaW5hIiksXQpnPWdncGxvdChub19jaGluYSxhZXMoQ291bnRyeSkpKwogIGdlb21faGlzdG9ncmFtKGZpbGw9InNreWJsdWUiLCBjb2xvcj0id2hpdGUiLCBzdGF0ID0gImNvdW50IikrCiAgZ2d0aXRsZSgiSGlzdG9ncmFtIG9mIG51bWJlciBvZiB1cmJhbiBhcmVhcyB3aXRob3V0IENoaW5hIikrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSkKZwpgYGAKCiogSW4gdGhpcyBoaXN0b2dyYW0sIGBJbmRvbmVzaWFgIHRha2VzIHRoZSBzZWNvbmQgcGxhY2UgYW5kIGBKYXBhbmAgdGFrZXMgdGhlIHRoaXJkIGluIHRoZSBudW1iZXIgb2YgdXJiYW4gYXJlYXMuIFRoZXkgYWxzbyBkb21pbmF0ZSB0aGUgcmVzdCBvZiBjb3VudHJpZXMgYnV0IHdpdGggbXVjaCBmZXdlciBhbW91bnQgb2YgdXJiYW4gYXJlYXMgY29tcGFyZWQgdG8gYENoaW5hYC4gU29tZSBvZiB0aGUgY291bnRyaWVzIGxpa2UgQnJ1bmVpIG1heSBvbmx5IGhhdmUgYSBmZXcgdXJiYW4gYXJlYSBpbiBvdXIgZGF0YXNldCBiZWNhdXNlIHN1Y2ggY291bnRyaWVzIGFyZSBzbyBzbWFsbCBpbiB0ZXJtcyBvZiB1cmJhbiBsYW5kIHNpemUgYW5kIHVyYmFuIHBvcHVsYXRpb24uIEluIHRoaXMgY2FzZSwgc3VjaCBjb3VudHJpZXMgd2lsbCBub3QgaW1wYWN0IG11Y2ggYWJvdXQgb3VyIGFuYWx5c2lzIG9mIEVhc3QgQXNpYW4gdXJiYW5pemFpdG9uIGluIGdlbmVyYWwuCgoqKioKIyMjIyBWYXJpYWJsZSAyOiBgQXZlcmFnZSBhbm51YWwgcmF0ZSBvZiBpbmNyZWFzZSBpbiB1cmJhbiBsYW5kIDIwMDAgLSAyMDEwICglKWAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnPWdncGxvdChkYXRhMixhZXMoYEF2ZXJhZ2UgYW5udWFsIHJhdGUgb2YgaW5jcmVhc2UgaW4gdXJiYW4gbGFuZCAyMDAwIC0gMjAxMCAoJSlgKSkrCiAgZ2VvbV9oaXN0b2dyYW0oZmlsbD0ic2t5Ymx1ZSIsIGNvbG9yPSJ3aGl0ZSIpKwogIGdndGl0bGUoIkhpc3RvZ3JhbSBvZiBBdmVyYWdlIGFubnVhbCByYXRlIG9mIGluY3JlYXNlIGluIHVyYmFuIGxhbmQgMjAwMCAtIDIwMTAiKQpnCmBgYAoKYGBge3J9CmdncGxvdChkYXRhMiwgYWVzKHg9IiIseT1gQXZlcmFnZSBhbm51YWwgcmF0ZSBvZiBpbmNyZWFzZSBpbiB1cmJhbiBsYW5kIDIwMDAgLSAyMDEwICglKWApKSsKZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3VyPSJyZWQiLCBvdXRsaWVyLnNoYXBlPTE2LAogICAgICAgICAgICAgb3V0bGllci5zaXplPTIsIG5vdGNoPVQpCmBgYAoKKiBUaGUgaGlzdG9ncmFtIHNob3dzIHRoYXQgZnJvbSAyMDAwIHRvIDIwMTAgaW4gRWFzdCBBc2lhLCB1cmJhbiBsYW5kIHNpemUgaW5jcmVhc2VzIHdpdGggdXJiYW5pemF0aW9uLiBNb3N0IG9mIHVyYmFuIGFyZWFzIGRvIGhhdmUgdGhlaXIgdXJiYW4gbGFuZCBpbmNyZWFzZSBhdCB0aGUgYXZlcmFnZSBhbm51YWwgcmF0ZSBmcm9tIDAlIHRvIDUlLCBwcmVmZXJhYmx5IDAlLiBGZXcgdXJiYW4gYXJlYXMgaW5jcmVhc2UgYmV5b25kIGFubnVhbCByYXRlIG9mIDEwJS4gQnV0IG5vIHVyYmFuIGFyZWEgc2hyaW5rcyBkdXJpbmcgdXJiYW5pemF0aW9uLiBUaGlzIGluZGljYXRlcyB0aGF0IHRoZSBleHBhbmRpbmcgdXJiYW4gYXJlYXMgaXMgbmVjZXNzYXJ5IGZvciB1cmJhbml6YXRpb24gcHJvY2VzcyBldmVuIHRob3VnaCBhdCByZWxhdGl2ZWx5IGxvdyByYXRlLiBJbiB0ZXJtcyBvZiBkYXRhIHF1YWxpdHksIHRoaXMgdmFyaWFibGUgaXMgZ2VuZXJhbGx5IGdvb2QgZm9yIG91ciBhbmFseXNpcyBldmVuIHdpdGggZmV3IG91dGxpZXJzLiBUaGUgYm94cGxvdCBzaG93cyB0aGF0IGFsbCBvdXRsaWVycyBhcmUgaW4gdGhlIGxhcmdlciBzaWRlIG9mIHRoZSB2YXJpYWJsZSB2YWx1ZXMuIFdlIGNhbiB0YWtlIHRob3NlIG91dGxpZXJzIG91dCBhbmQgYW5hbHl6ZSB0aGVtIGluZGl2aWR1YWxseSB0byBzZWUgdGhlIHJlYXNvbiB3aHkgdGhlIHJhdGUgaXMgc28gaGlnaC4KCioqKgojIyMjIFZhcmlhYmxlIDM6IGBBdmVyYWdlIGFubnVhbCByYXRlIG9mIGNoYW5nZSBvZiB1cmJhbiBwb3B1bGF0aW9uICglKWAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnPWdncGxvdChkYXRhMixhZXMoYEF2ZXJhZ2UgYW5udWFsIHJhdGUgb2YgY2hhbmdlIG9mIHVyYmFuIHBvcHVsYXRpb24gKCUpYCkpKwogIGdlb21faGlzdG9ncmFtKGZpbGw9InNreWJsdWUiLCBjb2xvcj0id2hpdGUiKSsKICBnZ3RpdGxlKCJIaXN0b2dyYW0gb2YgQXZlcmFnZSBhbm51YWwgcmF0ZSBvZiBpbmNyZWFzZSBpbiB1cmJhbiBwb3B1bGF0aW9uIikKZwpgYGAKYGBge3J9CmdncGxvdChkYXRhMiwgYWVzKHg9IiIseT1gQXZlcmFnZSBhbm51YWwgcmF0ZSBvZiBjaGFuZ2Ugb2YgdXJiYW4gcG9wdWxhdGlvbiAoJSlgKSkrCmdlb21fYm94cGxvdChvdXRsaWVyLmNvbG91cj0icmVkIiwgb3V0bGllci5zaGFwZT0xNiwKICAgICAgICAgICAgIG91dGxpZXIuc2l6ZT0yLCBub3RjaD1UKQpgYGAKCiogVGhpcyBoaXN0b2dyYW0gc2hvd3MgdGhhdCBmcm9tIDIwMDAgdG8gMjAxMCwgbW9zdCBvZiB0aGUgdXJiYW4gYXJlYXMgaW4gRWFzdCBBc2lhIGhhdmUgaW5jcmVhc2VkIGluIHVyYmFuIHBvcHVsYXRpb24gc2l6ZSB3aGlsZSBmZXcgaGF2ZSBkZWNyZWFzZWQgaW4gdXJiYW4gcG9wdWxhdGlvbiBzaXplLiBUaGUgYm94cGxvdCBzaG93cyB0aGF0IHRoZXJlIGFyZSBzb21lIG91dGxpZXJzIG9uIGJvdGggc2lkZXMgYnV0IHRoZSBvdXRsaWVycyBzZWVtIHJlYXNvbmFibGUgc2luY2Ugc29tZSB1cmJhbiBhcmVhcyBncm93IG11Y2ggZmFzdGVyIHRoYW4gb3RoZXJzIGluIHBvcHVsYXRpb24uIFRoZSByYW5nZSBvZiB0aGUgcmF0ZSBvZiBjaGFuZ2Ugb2YgdXJiYW4gcG9wdWxhdGlvbiBpcyBhY2NlcHRhYmxlIGFuZCB0aGUgZGlzdHJpYnV0aW9uIGlzIHJvdWdseSBub3JtYWwgYW5kIHRoaXMgdmFyaWFibGUgaXMgZ29vZCB0byB1c2UgaW4gdGhlIGFuYWx5c2lzLgoKKioqCiMjIyMgVmFyaWFibGUgNDogYFVyYmFuIGV4cGFuc2lvbiBwZXIgYWRkaXRpb25hbCB1cmJhbiBpbmhhYml0YW50IChzcS4gbS4vIHBlcnNvbilgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZz1nZ3Bsb3QoZGF0YTIsYWVzKGBVcmJhbiBleHBhbnNpb24gcGVyIGFkZGl0aW9uYWwgdXJiYW4gaW5oYWJpdGFudCAoc3EuIG0uLyBwZXJzb24pYCkpKwogIGdlb21faGlzdG9ncmFtKGZpbGw9InNreWJsdWUiLCBjb2xvcj0id2hpdGUiKSsKICBnZ3RpdGxlKCJIaXN0b2dyYW0gb2YgVXJiYW4gZXhwYW5zaW9uIHBlciBhZGRpdGlvbmFsIHVyYmFuIGluaGFiaXRhbnQgKE9yaWdpbmFsKSIpCmcKYGBgCgpgYGB7cn0KZ2dwbG90KGRhdGEyLCBhZXMoeD0iIix5PWBVcmJhbiBleHBhbnNpb24gcGVyIGFkZGl0aW9uYWwgdXJiYW4gaW5oYWJpdGFudCAoc3EuIG0uLyBwZXJzb24pYCkpKwpnZW9tX2JveHBsb3Qob3V0bGllci5jb2xvdXI9InJlZCIsIG91dGxpZXIuc2hhcGU9MTYsCiAgICAgICAgICAgICBvdXRsaWVyLnNpemU9Miwgbm90Y2g9VCkKYGBgCiogQm90aCB0aGUgaGlzdG9ncmFtIGFuZCB0aGUgYm94cGxvdCBvZiBgVXJiYW4gZXhwYW5zaW9uIHBlciBhZGRpdGlvbmFsIHVyYmFuIGluaGFiaXRhbnQgKHNxLiBtLi8gcGVyc29uKWAgc2hvd3MgdGhhdCB0aGVyZSBhcmUgc2V2ZXJhbCBvdXRsaWVycyBpbiB0aGlzIHZhcmlhYmxlLiBJbiBhZGRpdGlvbiwgdGhlcmUgaXMgb25lIG91dGxpZXIgd2l0aCBleHRyZW1lbHkgbmVnYXRpdmUgdmFsdWUgdGhhdCBtYWtlcyB0aGUgdHdvIHBsb3RzIGxvb2sgc3RyYW5nZS4gQWxzbywgdGhlcmUgYXJlIHNvbWUgb3RoZXIgb3V0bGllcnMgd2l0aCBzbWFsbGVyIGRldmlhdGlvbiBmcm9tIHRoZSBtb3N0IG9mIHRoZSBkYXRhIHZhbHVlcyBhbmQgd2UgY2FuIGV4Y2x1ZGUgdGhlbSB0byBzZWUgYSBjbGVhcmVyIGRpc3RyaWJ1dGlvbiBvZiB0aGlzIHZhcmlhYmxlLgoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQptb3N0ID0gZGF0YTJbZGF0YTIkYFVyYmFuIGV4cGFuc2lvbiBwZXIgYWRkaXRpb25hbCB1cmJhbiBpbmhhYml0YW50IChzcS4gbS4vIHBlcnNvbilgPi0xZSswMyZkYXRhMiRgVXJiYW4gZXhwYW5zaW9uIHBlciBhZGRpdGlvbmFsIHVyYmFuIGluaGFiaXRhbnQgKHNxLiBtLi8gcGVyc29uKWA8MjAwMCxdCmc9Z2dwbG90KG1vc3QsYWVzKGBVcmJhbiBleHBhbnNpb24gcGVyIGFkZGl0aW9uYWwgdXJiYW4gaW5oYWJpdGFudCAoc3EuIG0uLyBwZXJzb24pYCkpKwogIGdlb21faGlzdG9ncmFtKGZpbGw9InNreWJsdWUiLCBjb2xvcj0id2hpdGUiLGJpbndpZHRoID0gNTApKwogIGdndGl0bGUoIkhpc3RvZ3JhbSBvZiBVcmJhbiBleHBhbnNpb24gcGVyIGFkZGl0aW9uYWwgdXJiYW4gaW5oYWJpdGFudCAobW9kaWZpZWQpIikKZwpgYGAKCiogSW4gdGhpcyBoaXN0b2dyYW0sIHdpdGggZWxpbWluYXRpb24gb2YgdmFsdWVzIGJlbG93IC0xMDAwIGFuZCBiZXlvbmQgMjAwMCwgd2UgZ2V0IGEgbXVjaCBuaWNlciB2aXN1YWxpemF0aW9uIG9mIHRoZSBkaXN0cmlidXRpb24gb2YgVXJiYW4gZXhwYW5zaW9uIHBlciBhZGRpdGlvbmFsIHVyYmFuIGluaGFiaXRhbnQgZnJvbSAyMDAwIHRvIDIwMTAuIEl0IHNob3dzIHRoYXQgbW9zdCBvZiB0aGUgdXJiYW4gYXJlYXMgaW4gRWFzdCBBc2lhIGhhdmUgYXBwcm94aW1hdGVseSAwIHRvIDMwMCB1cmJhbiBleHBhbnNpb24gcGVyIGFkZGl0aW9uYWwgdXJiYW4gaW5oYWJpdGFudC4gVGhlcmUgYXJlIHN0aWxsIHNvbWUgdXJiYW4gYXJlYXMgaGF2ZSBuZWdhdGl2ZSB2YWx1ZSBhbmQgdGhpcyBjb3JyZXNwb25kcyB0byB0aGUgdHdvIGhpc3RvZ3JhbXMgYWJvdmUgd2hpY2ggc2hvdyB0aGF0IGluIHRob3NlIHVyYmFuIGFyZWFzLCB0aGVpciBsYW5kIHNpemVzIGluY3JlYXNlIHdoaWxlIHRoZWlyIHBvcHVsYXRpb24gZGVjcmVhc2UuCgoKKioqCiMjIDQuIEV4ZWN1dGl2ZSBTdW1tYXJ5CiogRWFzdCBBc2lhIGV4cGVyaWVuY2VkIHJhcGlkIHVyYmFuIGV4cGFuc2lvbiBhbmQgdXJiYW4gcG9wdWxhdGlvbiBncm93dGggYmV0d2VlbiAyMDAwIGFuZCAyMDEwLiBUaGUgcmVnaW9uIGhhZCA4NjkgdXJiYW4gYXJlYXMgd2l0aCBtb3JlIHRoYW4gMTAwLDAwMCBwZW9wbGUgaW4gMjAxMDsgNjAwIG9mIHRoZXNlIGFyZWFzIHdlcmUgaW4gQ2hpbmEuIEFsdGhvdWdoIGEgbGFyZ2UgYW1vdW50IG9mIG5ldyB1cmJhbiBleHBhbnNpb24gb2NjdXJyZWQgKG1vcmUgdGhhbiAyOCwwMDAgc3F1YXJlIGtpbG9tZXRlcnMpLCB1cmJhbiBwb3B1bGF0aW9ucyBncmV3IGV2ZW4gZmFzdGVyIHRoYW4gdXJiYW4gbGFuZC4KCiFbZmlndXJlIDFdKGhpc3QuanBnKQoKKiBVcmJhbiBwb3B1bGF0aW9uIGRlbnNpdGllcyBpbiBtb3N0IGNvdW50cmllcyBpbiBFYXN0IEFzaWEgaGF2ZSBpbmNyZWFzZWQgb24gYXZlcmFnZS4gT25lIG9mIHRoZSBzdXJwcmlzaW5nbHkgaW1wb3J0YW50IGZpbmRpbmdzIGlzIHRoYXQsIGRlc3BpdGUgaW4gY29tbW9uIHNlbnNlIHRoYXQgdGhlIGxhcmdlIGFtb3VudCBvZiB1cmJhbiBncm93dGggcmVzdWx0aW5nIGluIGFyZWEgc3ByYXdsaW5nIGFuZCBkZW5zaXR5IGRlY2xpbmluZywgdXJiYW4gYXJlYXMgaW4gRWFzdCBBc2lhIGluIGZhY3QgYXBwZWFyIHRvIGJlY29tZSBzbGlnaHRseSBkZW5zZXIgb24gYXZlcmFnZSAoZnJvbSA1LDQwMCBwZW9wbGUgcGVyIHNxdWFyZWQga2lsb21ldGVyIGluIDIwMDAgdG8gNSw4MDAgcGVvcGxlIHBlciBzcXVhcmVkIGtpbG9tZXRlciBpbiAyMDEwKS4gSG93ZXZlciwgaXQgaXMgbm90aWNlYWJsZSB0aGF0IHN1Y2ggaGlnaCBhbmQgaW5jcmVhc2luZyBkZW5zaXR5IGlzIG5vdCBhIHVuaWZvcm0gdHJlbmQgYWNyb3NzIGFsbCBjb3VudHJpZXMgaW4gRWFzdCBBc2lhLiBDb3VudHJpZXMgd2l0aCByZWxhdGl2ZWx5IGxvd2VyIGVjb25vbXkgdm9sdW1uIHN1Y2ggYXMgSW5kb25lc2lhIGFuZCBUaW1vci1MZXN0ZSBoYWQgbXVjaCBoaWdoZXIgZGVuc2l0aWVzIGFuZCBsYXJnZXIgaW5jcmVhc2VzIGluIGRlbnNpdHkuIAoqIERlc3BpdGUgdGhlIGh1Z2UgZ3Jvd3RoIGluIGl0cyB1cmJhbiBwb3B1bGF0aW9uLCBDaGluYeKAmXMgdXJiYW4gcG9wdWxhdGlvbiBkZW5zaXR5IChmcm9tIDUyNjAgcGVvcGxlIHBlciBzcXVhcmVkIGtpbG9tZXRlcnMgaW4gMjAwMCB0byA1LDM0MCBwZW9wbGUgcGVyIHNxdWFyZWQga2lsb21ldGVyIGluIDIwMTApIHJlbWFpbmVkIHN0YWJsZSwgYW5kIGxvd2VyIHRoYW4gdGhlIGF2ZXJhZ2UgZm9yIHdob2xlIEVhc3QgQXNpYW4gcmVnaW9uLiBUaGlzIGNhbiBwcm9iYWJseSBiZSBleHBsYWluZWQgYnkgdGhhdCB0aGUgYWNjb21wYW55aW5nIHVyYmFuIHNwYXRpYWwgZXhwYW5zaW9uIGlzIHNvIHJhcGlkIGFsc28gd2l0aCB0aGUgYmFycmllcnMgdG8gbWlncmF0aW9uLiBMZXQncyB0YWtlIGEgbG9vayBvZiBKYXBhbiwgd2hpY2ggd2FzIHRoZSBsYXJnZXN0IGVjb25vbXkgZW50aXR5IGluIEVhc3QgQXNpYSBiZWZvcmUgMjAxMC4gVW5saWtlIENoaW5hIHdpdGggdmFzdCB0ZXJyaXRvcnksIEphcGFuIGhhcyB2ZXJ5IGxpbWl0ZWQgbGFuZCBmb3IgdXJiYW4gZXhwYW5zaW9uIGJ1dCBoYXMgbGFyZ2UgcG9wdWxhdGlvbi4gVGhpcyBtYXkgZXhwbGFpbiB3aHkgdGhhdCBKYXBhbiBoYXMgbXVjaCBsYXJnZXIgaW5jcmVhc2UgaW4gcG9wdWxhdGlvbiBkZW5zaXR5IHRoYW4gQ2hpbmEgKDc4IHBlb3BsZSBwZXIgc3F1YXJlZCBraWxvbWV0ZXJzIGluY3JlYXNlZCBmb3IgQ2hpbmEgYW5kIDQ1MyBmb3IgSmFwYW4gZnJvbSAyMDAwIHRvIDIwMTApLiAKKiBJbiBjb250cmFzdCBvZiBhIGxhcmdlIGVjb25vbXkgZW50aXRpZXMgbGlrZSBDaGluYSBhbmQgSmFwYW4sIGluIEluZG9uZXNpYSwgd2hpY2ggaGFkIGEgbGFyZ2UganVtcCBpbiB1cmJhbiBwb3B1bGF0aW9uIGRlbnNpdHksIGFuZCBpbiBtYW55IG90aGVyIGNvdW50cmllcywgcG9wdWxhdGlvbnMgbWlncmF0ZSBmcmVlbHksIHdoaWxlIHRoZSBjb25zdHJhaW50IGlzIG9uIHByb2R1Y2luZyBuZXcgdXJiYW4gYXJlYSB3aXRoIGluZnJhc3RydWN0dXJlIGFuZCBob3VzaW5nLiBPdXRzaWRlIENoaW5hLCA5MiBwZXJjZW50IG9mIHVyYmFuIGFyZWFzIGluIHRoZSByZWdpb24gYmVjYW1lIGRlbnNlciBkdXJpbmcgdGhpcyBwZXJpb2QuIEl0IGlzIGludGVyZXN0aW5nIHRoYXQgU291dGggS29yZWEgYW5kIFRhaXdhbiAoY29uc2lkZXJlZCBhcyBhbiBpbmRlcGVuZGVudCBlbnRpdHkgaW4gdXJiYW5pemF0aW9uKSBhcmUgYm90aCBkZXZlbG9wZWQgd2hpbGUgaGF2ZSBkZWNyZWFzZSBpbiB1cmJhbiBwb3B1bGF0aW9uIGRlbnNpdHkuIFNvdXRoIEtvcmVhIGhhcyBhIHNtYWxsIGRlY3JlYXNlLCBpbmRpY2F0aW5nIGEgcmVsYXRpdmVseSBzdGFibGUgdXJiYW4gcG9wdWxhdGlvbiBkZW5zaXR5LiBCdXQgVGFpd2FuIGhhcyBhIGxhcmdlIGRlY3JlYXNlIGluIHVyYmFuIHBvcHVsYXRpb24gZGVuc2l0eS4KCgohW2ZpZ3VyZSAyXShzY2F0dG9yLmpwZykKCiogV2hlbiBhbmFseXppbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGF2ZXJhZ2UgYW5udWFsIHJhdGUgb2YgaW5jcmVhc2UgaW4gdXJiYW4gbGFuZCAyMDAwLTIwMTAgKCUpIGFuZCBhdmVyYWdlIGFubnVhbCByYXRlIG9mIGluY3JlYXNlIGluIHVyYmFuIHBvcHVsYXRpb24gMjAwMC0yMDEwICglKSBmb3IgZWFjaCB1cmJhbiBhcmVhLCBpdCBpcyBpbXBvcnRhbnQgdG8gdGFrZSB0aGUgY291bnRyeSB0aGUgdXJiYW4gYXJlYSBiZWxvbmdzIHRvIGFuZCB0aGUgYm91bmRhcnkgdHlwZSBpdCBiZWxvbmdzIHRvLiBUaGUgc2NhdHRvciBwbG90IGRpdmlkZXMgdGhlIGRvdHMgaW50byBjb3VudHJpZXMuIEluIGdlbmVyYWwsIHRoZSBhdmFyYWdlIGFubnVhbCByYXRlIG9mIGluY3JlYXNlIGluIHVyYmFuIGxhbmQgaXMgcG9zaXRpdmVseSByZWxhdGVkIHRvIHRoZSBhdmFyYWdlIGFubnVhbCByYXRlIG9mIGluY3JlYXNlIGluIHVyYmFuIHBvcHVsYXRpb24uIEFsbCB1cmJhbiBhcmVhcyBoYXZlIG5vbi1uZWdhdGl2ZSBhdmVyYWdlIGFubnVhbCByYXRlIG9mIGluY3JlYXNlIGluIHVyYmFuIGxhbmQgd2hpbGUgc29tZSB1cmJhbiBhcmVhcyBoYXZlIG5lZ2F0aXZlIGF2ZXJhZ2UgYW5udWFsIHJhdGUgb2YgZGVjcmVhc2UgaW4gdXJiYW4gcG9wdWxhdGlvbi4gVGhpcyBzaW1wbHkgc2hvd3MgdGhhdCBhbGwgdGhlIHVyYmFuIGFyZWFzIHdlcmUgZXhwYW5kaW5nIGZyb20gMjAwMCB0byAyMDEwIHdoaWxlIHNvbWUgaGF2ZSBpdHMgcG9wdWxhdGlvbiBkZWNyZWFzZWQuIE1vc3Qgb2YgdGhlIHVyYmFuIGFyZWFzIGhhdmUgc21hbGwgY2hhbmdlIGluIHBvcHVsYXRpb24gYW5kIGxhbmQuIAoKKiBVbnN1cHJpc2luZ2x5IENoaW5hIGFjY291bnRzIGZvciBtb3N0IG9mIHRoZSBkb3RzIGluIHRoZSBncmFwaC4gSW4gYWRkaXRpb24sIGFsbW9zdCBhbGwgdGhlIHVyYmFuIGFyZWFzIHRoYXQgaGF2ZSBhdmFyYWdlIGFubnVhbCByYXRlIG9mIGluY3JlYXNlIGluIHVyYmFuIGxhbmQgMjAwMC0yMDEwICglKSBvdmVyIDUlIGJlbG9uZyB0byBDaGluYSwgaW5kaWNhdGluZyBDaGluYSBpcyBleHBhbmRpbmcgaXRzIHVyYmFuIGxhbmQgZmFzdGVyIHRoYW4gYW55IG90aGVyIGNvdW50cmllcyBpbiBFYXN0IEFzaWEuIElmIHRoZSB0d28gcmF0ZXMgZm9yIHVyYmFuIGxhbmQgYW5kIHBvcHVsYXRpb24gYXJlIHRoZSBzYW1lICh0aGUgYmxhY2sgbGluZSB3aXRoIGludGVyY2VwdCBvZiAwIGFuZCBzbG9wZSBvZiAxKSwgaXQgc2hvd3MgdGhlIHBvcHVsYXRpb24gZGVuc2l0eSByZW1haW5zIHRoZSBzYW1lLiBUaGUgZG90cyB0aGF0IGxpZSBhYm92ZSB0aGUgYmxhY2sgbGluZSBhcmUgdGhlIHVyYmFuIGFyZWFzIHRoYXQgaGF2ZSBpbmNyZWFzaW5nIHBvcHVsYXRpb24gZGVuc2l0eSBhbmQgdmljZSB2ZXJzYS4gTW9zdCBvZiBDaGluYSdzIHVyYmFuIGFyZWFzIGhhdmUgZGVjcmVhc2luZyBwb3B1bGF0aW9uIGRlbnNpdHkuIAoKKiBBbHRob3VnaCB0aGUgcG9wdWxhdGlvbiBkZW5zaXR5IGlzIGEgZnJlcXVlbnQgdG9waWMgb2YgZGlzY3Vzc2lvbiBpbiB1cmJhbml6YXRpb24sIGFub3RoZXIgaW1wb3J0YW50IGNvbnNpZGVyYXRpb24gZnJvbSB0aGUgcG9pbnQgb2YgdmlldyBvZiB1cmJhbiBtYW5hZ2VtZW50IGlzIHRoZSB3YXkgaW4gd2hpY2ggYWRtaW5pc3RyYXRpdmUgYm91bmRhcmllcyBhcmUgYXJyYW5nZWQgaW4gcmVsYXRpb24gdG8gYnVpbHQtdXAgZXh0ZW50cyBvZiB0aGUgdXJiYW4gYXJlYSwgaW5kZXBlbmRlbnQgb2Ygc2l6ZS4gVGhlIGZvbGxvd2luZyBhcmUgdGhlIGRlZmluaXRpb25zIG9mIHRoZSB0aHJlZSBib3VuZGFyeSB0eXBlczoKICAgICogMS4gYGNvbnRhaW5lZCB1cmJhbiBhcmVhc2A6IHRoZSBlbnRpcmUgYnVpbHQtdXAgYXJlYSBmYWxscyB3aXRoaW4gdGhlIHJlbGV2YW50IGFkbWluaXN0cmF0aXZlIGJvdW5kYXJ5LCB0aGF0IGlzLCB0aGUgYm91bmRhcnkgcmVwcmVzZW50aW5nIHRoZSB1bml0IG9mIGdvdmVybm1lbnQgcmVzcG9uc2libGUgZm9yIHVyYmFuIG1hbmFnZW1lbnQuCiAgICAqIDIuIGBzcGlsbG92ZXIgdXJiYW4gYXJlYXNgOiB1cmJhbml6YXRpb24gZXh0ZW5kcyBiZXlvbmQgdGhlIGJvdW5kYXJ5IG9mIHRoZSBqdXJpc2RpY3Rpb24gaW4gd2hpY2ggdXJiYW4gYWN0aXZpdHkgb3JpZ2luYXRlZCAodGhlIGRvbWluYW50IGNpdHkpLCBpbnRvIHN1cnJvdW5kaW5nIGp1cmlzZGljdGlvbnMuCiAgICAqIDMuIGBmcmFnbWVudGVkIHVyYmFuIGFyZWFzYDogdXJiYW5pemF0aW9uIHdpdGggc2V2ZXJhbCBhZG1pbmlzdHJhdGl2ZSBqdXJpc2RpY3Rpb25zIGFuZCBzZXZlcmFsIG9yaWdpbmFsIGNlbnRlcnMgdGhhdCBvdmVyIHRpbWUgbWVyZ2UgYWNyb3NzIGJvdW5kYXJpZXMKICAgIAoqIEluIHRlcm1zIG9mIGFkbWluaXN0cmF0aXZlIGJvdW5kYXJpZXMsIG1vc3Qgb2YgdGhlIHVyYmFuIGFyZWFzIHdpdGggb3ZlciA1JSBhdmVyYWdlIGFubnVhbCByYXRlIG9mIGluY3JlYXNlIGluIHVyYmFuIGxhbmQgYXJlIGBjb250YWluZWRgIGFuZCBhbGwgb2YgdGhlIHVyYmFuIGFyZWFzIHdpdGggb3ZlciAxMCUgYXZlcmFnZSBhbm51YWwgcmF0ZSBvZiBpbmNyZWFzZSBpbiB1cmJhbiBsYW5kIGFyZSBgY29udGFpbmVkYC4gYGNvbnRhaW5lZGAgdXJiYW4gYXJlYXMgYXJlIHVzdWFsbHkgcmVsYXRpdmVseSBzbWFsbCBjaXR5IHVyYmFuIGFyZWFzIHRoYXQgcmVxdWlyZSBtdWNoIGZhc3RlciB1cmJhbiBleHBhbnNpb24uIFNpbmNlIENoaW5hIGlzIHRoZSBsYXJnZXN0IGFuZCBmYXN0ZXN0IGRldmVsb3BpbmcgY291bnRyeSBpbiBFYXN0IEFzaWEsIHVuc3VycHJpc2luZ2x5IENoaW5hIGhhcyBhIGxvdCBvZiBzbWFsbCBhbmQgbWVkaXVtLXNpemUgdXJiYW4gYXJlYXMgZXhwYW5kaW5nIHZlcnkgZmFzdCB0byBrZWVwIHVwIHRoZSBwYWNlIG9mIHRoZSB0aGUgZGV2ZWxvcG1lbnQgb2YgQ2hpbmEgYXMgYSB3aG9sZS4KCiFbZmlndXJlIDNdKHBlci5qcGVnKQoKKiBGaWd1cmUgMyBzaG93cyB0aGF0IGBmcmFnbWVudGF0aW9uYCBpbmNyZWFzZXMgc3RlYWRpbHkgd2hpbGUgYGNvbnRhaW5lZGAgZGVjcmVhc2VzIHdpdGggaW5jcmVhc2luZyBwb3B1bGF0aW9uIHNpemUsIGFzIG9uZSBtaWdodCBleHBlY3QuIGBTcGlsbG92ZXJgIHRha2VzIHRoZSBtYWpvcml0eSBmb3IgdXJiYW4gYXJlYXMgd2l0aCAwLjUgbWlsbGlvbiB0byAxIG1pbGxpb24gcGVvcGxlIGFuZCBkZWNyZWFzZSBzdGVhZGlseSBubyBtYXR0ZXIgcG9wdWxhdGlvbiBzaXplIGluY3JlYXNlcyBvciBkZWNyZWFzZXMuIFRoZSBtYWpvcml0eSBvZiB1cmJhbiBhcmVhcyB3aXRoIGZld2VyIHRoYW4gMC41IG1pbGxpb24gcGVvcGxlIGFyZSBjb250YWluZWQgd2l0aGluIHRoZWlyIGJvdW5kYXJpZXMsIHdoZXJlYXMgYWxsIHRoZSBtZWdhY2l0aWVzIChsYXJnZXIgdGhhbiAxMCBtaWxsaW9uIHBlb3BsZSkgYXJlIGZyYWdtZW50ZWQuIEFzIG1lbnRpb25lZCBwcmV2aW91c2x5LCB0aGUgbGFyZ2VzdCBhbW91bnQgb2YgdXJiYW4gc3BhdGlhbCBleHBhbnNpb24gdGhhdCBpcywgaW5jcmVhc2UgaW4gYWJzb2x1dGUgbGFuZCBhcmVhIGhhcyBvY2N1cnJlZCBpbiB0aGUgc21hbGwgYW5kIG1lZGl1bS1zaXplZCB1cmJhbiBhcmVhcywgbWFueSBvZiB3aGljaCBhcmUgb24gdGhlIGN1c3Agb2YgYmVjb21pbmcgc3BpbGxvdmVyIG9yIGZyYWdtZW50ZWQgdXJiYW4gYXJlYXMuIFRoZXNlIHVyYmFuIGFyZWFzIGNhbiBwcmVwYXJlIGluIGFkdmFuY2UgZm9yIHRoZSBjaGFsbGVuZ2VzIG9mIGZyYWdtZW50YXRpb24gYnkgcHV0dGluZyBpbiBwbGFjZSBtZWNoYW5pc21zIGZvciBjb2xsYWJvcmF0aW9uIGFjcm9zcyBhZG1pbmlzdHJhdGl2ZSBib3VuZGFyaWVzIHN1Y2ggYXMgUGVhcmwgUml2ZXIgRGVsdGEgdXJiYW4gYXJlYXMsIGEgZnJhZ21lbnRlZCB1cmJhbiBhcmVhIHdoaWNoIGNvbnRhaW5zIGNpdGllIG9mIEd1YW5nemhvdSwgU2hlbnpoZW4sIEZvc2hhbiwgYW5kIERvbmdndWFuLiAKCiMjIDUuIE1haW4gQW5hbHlzaXMKCiMjIyBJbnRyb2R1Y3Rpb24gIAoKVXJiYW5pemF0aW9uIGlzIHRoZSBtb3N0IGNvbW1vbiBwaGVub21lbm9uIGZvciB0aGUgbW9kZXJuIHNvY2lldGllcy4gVGhlIG5hdHVyZSBvZiBzb2NpZXR5IGlzIHNoaWZ0aW5nIGZyb20gYSBkZXBlbmRlbmN5IG9mIHJ1cmFsIGFyZWEgdG8gYSBtb3JlIGFuZCBtb3JlIHVyYmFuIGFyZWEuIEhvd2V2ZXIsIHRoZXJlIGFyZSB2YXJpb3VzIGlzc3VlcyBhY2NvbXBhbnlpbmcgd2l0aCB0aGUgc2lnbmlmaWNhbnQgdXJiYW5pemF0aW9uLCBzdWNoIGFzIG92ZXItcG9wdWxhdGlvbiwgcG9sbHV0aW9uLCBlY29ub21pYyBlZmZlY3RzIGFuZCBldGMuIFRoZXJlZm9yZSwgZGV0ZWN0aW5nIGEgc3VzdGFpbmFibGUgYW5kIGVxdWl0YWJsZSBwYXRoIG9mIHVyYmFuaXphdGlvbiBpcyBvbmUgb2YgdGhlIG1vc3QgY3JpdGljYWwgcHJvYmxlbXMgZm9yIHNvY2lhbCBzY2llbnRpc3RzLgoKSW4gb3VyIHByb2plY3QsIHZpc3VsaXphdGlvbnMgYXJlIGJhc2VkIG9uIHRoZSB1cmJhbml6YWVkIHNpdHVhdGlvbnMgaW4gRWFzdCBBc2lhIGJldHdlZW4gMjAwMCBhbmQgMjAxMCBjb2xsZWN0ZWQgYnkgdGhlIFdvcmxkIEJhbmsuIFRoZXJlZm9yZSwgdGhyb3VnaCBvdXIgcHJvamVjdCwgaXQgaXMgZWFzeSBmb3IgdXMgdG8gZ2V0IGEgY2xlYXIgdmlldyBvbiB0aGUgbWFnbml0dWRlIG9mIGNoYW5nZXMgdGhhdCBoYXBwZW5lZCBpbiBvbmUgZGVjb2RlLiBXaGF0IGlzIG1vcmUsIGl0IGNhbiBhbHNvIGZhY2lsaXRhdGUgdmlld2VycyB0byB0aGluayBhYm91IHRoZSBpbXBhY3RzIG9uIHRoZSBmb2xsb3dpbmcgeWVhcy4KCk91ciBkYXRhIGlzIGZyb20gIHRoZSA4NjkgdXJiYW4gYXJlYXMgaW4gdGhlIHJlZ2lvbiB3aXRoIHBvcHVsYXRpb25zIG92ZXIgMTAwLDAwMCBpbiAyMDEwCgojIyMgTWFwCgpJbiB0aGUgcHJvY2VzcyBvZiBjcmVhdGluZyB0aGUgaW50ZXJhY3RpdmUgbWFwcywgd2UgaW5jbHVkZSBzZXZlcmFsIHZhcmlhYmxlcywgbnVtZXJpY2FsIGFuZCBjYXRlZ29yaWNhbC4gQXQgdGhlIGZpcnN0IHNlbGVjdCwgdGhlIHZpZXdlciBjYW4gY2hvb3NlIHRoZSBgWWVhcmAgYW5kIGBCb3VuZGFyeWAgY2FuIGFsc28gYmUgc3BlY2lmaWVkLiBBdCB0aGUgZW5kLCB0aGUgdXNlciBjYW4gYWxzbyBjaG9vc2UgdGhlIGBtZWFzdXJlYCB3aGljaCBjYW4gYmUgYHVyYmFuIHBvcHVsYXRpb25gIGFuZCBgdXJiYW4gbGFuZGAgdG8gbG9vayBhdCB0aGUgZGlzdHJpYnV0aW9uIGFjcm9zcyBhcmVhcyBpbiB0aGUgbWFwLiBJbXBvcnRhbnRseSwgdGhlIHJhZGl1cyBvZiBjaWNsZXMgaW4gdGhlIG1hcCBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgYG1lYXN1cmVgIHRoYXQgdGhlIHVzZSBjaG9zZSBhbmQgdGhlIGNpcmNsZXMgYXJlIGNvbG9yZWQgYnkgdGhlIHBvcHVsYXRpb24gZGVuc2l0eS4gVGhyb3VnaHQgdGhlIG1hcCwgdGhlIHZpZXcgY2FuIGhhdmUgYSBjb21wcmVoZW5zaXZlIHVuZGVyc3RhbmRpbmcgb2YgdmFyaW91cyB2YXJpYWJsZXMgYWNyb3NzIHVyYmFuIGFyZWFzIGluIHRoZSBhY3R1YWwgcG9zaXRpb25zLiBXaGVuIHRoZSB2aWV3ZXIgcHV0cyB0aGUgY3Vyc29yIG9uIHRoZSBhY3R1YWwgcG9pbnRzLCBoZSBjYW4gZ2V0IHRoZSBhcmVhIG5hbWUgZm9yIHRoYXQgc3BlY2lmaWMgcG9pbnQuIAoKIVtNYXAxXShtYXAxLnBuZykKCiogYEZpbmRpbmcxYCBUaGVyZSBpcyBhIHNpZ25pZmljYW50IGluY3JlYXNlIG9mIHBvcHVsYXRpb24gaW4gdGhpcyBkZWNhZGUsIGFib3V0IDIwMCBtaWxsaW9uIHBlb3BsZSBhbmQgdGhpcyB3b3VsZCBiZSB0aGUgd29ybGQncyBzaXh0aC1sYXJnZXN0IHBvcHVsYXRpb24gaWYgd2UgY29uc2lkZXIgaXQgZm9yIGFueSBzaW5nbGUgY291bnRyeS4gSW4gZGV0YWlscywgdGhlcmUgd2VyZSA1ODAgbWlsbGlvbiBwZW9wbGUgbGl2aW5nIGluIHRoZXNlIDg2OSBjaXRpZXMgYW5kIGluIGp1c3QgdGVuIHllYXJzLCB0aGlzIG51bWJlciBqdW1wcyB0byA3ODAgbWlsbGlvbi4gSXQgaXMgbmVjZXNzYXJ5IGZvciBjaXRpZXMgdG8gY29uc2lkZXIgdGhlIGhvdXNpbmcgYW5kIGluZnJhc3RydWN0dXJlIGlzc3VlcyB3aXRoIHRoaXMgYW1vdW50IG9mIHBlb3BsZSBvZiB0aGUgbW92ZS4KICAKKiBgRmluZGluZzJgIFRoZXJlIGFyZSBzb21lIGdpYW50IG1lZ2FjaXRpZXMgaGFzIGVtZXJnZWQgZHVyaW5nIHRoZXNlIHRlbiB5ZWFycy4gVGhlcmUgYXJlIDggbWVnYWNpdGllcyB3aXRoIG1vcmUgdGhhbiAxMCBtaWxsaW9uIHBlb3BsZSBpbiAyMDEwLiAKCiogYEZpbmRpbmczYCBDaGluYSBpcyB0aGUgZG9taW5hdGluZyBjb3VudHJ5IGluIHRoaXMgdXJiYW5pemF0aW9uIHByb2Nlc3Mgc2luY2UgdGhlIG1ham9yaXR5IG9mIHVyYmFuIGFyZWFzIGFyZSBmcm9tIENoaW5hIGFuZCB0aGV5IGFsbCBoYXZlIHNpZ25pZmljYW50bHkgaW5jcmVhc2UgaW4gdGVybXMgb2YgbGFuZCBhcmVhIGFuZCBwb3B1bGF0aW9uLiBGb3IgZXhhbXBsZSwgdGhlIFBlYXJsIFJpdmVyIERlbHRhIGluIENoaW5hIGhhcyBvdmVydGFrZW4gVG9reW8gYXMgdGhlIHdvcmxkJ3MgbGFyZ2VzdCB1cmJhbiBhcmVhIGNvbnNpZGVyaW5nIGxhbmQgYXJlYSBhbmQgcG9wdWxhdGlvbi4KCiFbTWFwMl0obWFwMi5wbmcpCgohW01hcDNdKG1hcDMucG5nKQoqIGBGaW5kaW5nNGAgVGhlIHNpemUgYW5kIHBvcHVsYXRpb24gb2YgdXJiYW4gYXJlYXMgYXJlIGhpZ2hseSByZWxhdGVkIHRvIHRoZSBib3VuZGFyeSB0eXBlLiBBcyB3ZSBjYW4gZ2V0IGZyb20gdGhlIG1hcCwgaWYgd2UgZml4IGEgc2l6ZSBtZWFzdXJlIGFuZCBhZGp1c3QgdG8gdGhlIGJvdW5kYXJ5IHR5cGUsIHRoZSBhcHBlYXJhbmNlIG9mIG1lYXN1cmVzIGFjcm9zcyB1cmJhbiBhcmVhIGFyZSBncmVhdGx5IGRpZmZlcmVudC4KCiMjIyBEYXRhIEV4cGxvcmVyCgohW0V4cGxvcmVyXShleHBsb3Jlci5wbmcpCgpJbiB0aGlzIHRhYiwgd2UgaW5jbHVkZSBhIERUIHRhYmxlIGludG8gb3VyIHNoaW55IGFwcCwgd2hlcmUgcHJvdmlkZXMgdGhlIG1vc3QgZGlyZWN0IHdheXMgZm9yIHVzZXIgdG8gbG9vayBhdCB0aGUgZGF0YSBhbmQgZ2V0IGEgc2Vuc2Ugb2Ygd2hvbGUgZGF0YXNldC4gVGhlcmUgYXJlIHZhcmlvdXMgZnVuY3Rpb25hbGl0aWVzIGluIHRoaXMgdGFibGU6CiAgCiAgKiBgc2VhcmNoIGJhcmAgYXQgdGhlIHRvcCBvZiB0aGUgdGFibGUgdG8gc2VhcmNoIGJ5IGNvdW50cnksIGJvdW5kYXJ5IHR5cGUgb3IgdXJiYW4gYXJlYXMgYW5kIGV2ZW4gYWxsIG9mIHRoZW0KICAKICAqIGBzZWxlY3Rpb24gc2xpZGVyYCBiZWxvdyBhbGwgdGhlIGNvbHVtbiBuYW1lcyB0byBzZWxlY3Qgcm93cyBieSB0aGUgcmFuZ2Ugb2YgdmFyaWFibGVzCiAgCiAgKiBgZXh0ZW5zaW9uIGJ1dHRvbmAgdGhlIHRhYmxlIGluZm9ybWF0aW9uIG1heSBiZSBoaWRkZW4gYnkgdGhlIHNpemUgb2YgcGFnZXMgYW5kIHRoZSB1c2VyIGNhbiBsb29rIGF0IHRoZSB3aG9sZSBkYXRhIG9mIGVhY2ggcm93IGJ5IGNsaWNraW5nIG9uIHRoZSBncmVlZW4gYHBsdXNgIGJ1dHRvbgogIApUaGUgRGF0YSBFeHBsb3JlciB0YWJsZSBwcm92aWRlcyBhIHdheSBmb3Igdmlld3Mgd2hvIGxpa2UgcGxheWluZyB3aXRoIHJhdyBkYXRhIGFuZCBnZXQgYSBzZW5zZSBvZiBkYXRhc2V0LgoKIyMjIFNsb3BlIFBsb3RzCgpUaHJvdWdoIHRoZSBzbG9wZSBwbG90cywgd2UgY2FuIGdldCBhIGNsb3NlciBsb29rIG9mIHRoZSBhYnNvbHV0ZSBjaGFuZ2VzIG9mIHZhcmlvdXMgbWVhc3VyZSBhY3Jvc3MgY2l0aWVzLCBzdWNoIGFzIHBvcHVsYXRpb24sIGxhbmQgYXJlYSBhbmQgcG9wdWxhdGlvbiBkZW5zaXR5LiBJbiB0aGUgbGVmdCBzaWRlIG9mIHRoZSBzbG9wZSBwbG90LCBgbWVhc3VyZWAgc2VsZWN0ZWQgYnkgdXNlcnMgb2YgMjAwMCBhcmUgc2hvd2luZyB0aGVyZS4gSW4gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIHNsb3BlIHBsb3QsIHRoZSBwYWlyZWQgdmFyaWFibGUgb2YgMjAxMCBpcyBzaG93aW5nIHRoZXJlLiBXZSBpbmNsdWRlIGBMYW5kIGFyZWFgLCBgUG9wdWxhdGlvbiBEZW5zaXR5YCBhbmQgYFBvcHVsYXRpb25gIGludG8gb3VyIG1lYXN1cmUgc2VsZWN0aW9uLiBBZGRpdGlvbmFsbHksIHRoZSBjb2xvciBvZiBsaW5lcyBjYW4gYmUgZGV0ZXJtaW5lZCBieSBgQ291bnRyeWAgb3IgYEJvdW5kYXJ5IFR5cGVgLiBEZXBlbmRpbmcgb24gdGhlIGRpZmZlcmVudCBncm91cHMsIG1lYXN1cmUgdmFyaWFibGVzIGNhbiBoYXZlIGEgdmFyaWF0eSBvZiBwZXJmb3JtYW5jZXMgYWNyb3NzIGFyZWFzLiBBdCB0aGUgbWVhbiB0aW1lLCB0aGUgY2hhbmdlIHJhdGUgb2YgZWFjaCB2YXJpYWJsZSBmb3IgZXZlcnkgYXJlYSBjYW4gYWxzbyBiZSBzaG93ZWQgdGhyb3VnaCB0aGUgc2xvcGUgcGxvdHMuCgohW1Nsb3BlMl0oc2xvcGUyLnBuZykKCiogYEZpbmRpbmcxYCBJZiB3ZSBzZWxlY3QgdGhlIGBQb3B1bGF0aW9uYCBtZWFzdXJlLCB3ZSBjYW4gc2VlIHVyYmFuIHBvcHVsYXRpb24gaW4gMjAwMCBvbiB0aGUgbGVmdCBzaWRlIGFuZCBpbiAyMDEwIG9uIHRoZSByaWdodC4gSXQgY2FuIGFsc28gdmFyaWZ5IG91ciBvbmUgb2YgZmluZGluZ3MgZnJvbSB0aGUgTWFwIHRoYXQgdGhlIFBlYXJsIFJpdmVyIERlbHRhIEFyZWEgaW4gQ2hpbmEgaGFzIGJlY29tZSB0aGUgbGFyZ2VzdCB1cmJhbiBhcmVhIGluIEVhc3QgQXNpYSBhbmQgZXZlbiBpbiB0aGUgd29ybGQuIFdoYXQgaXMgbW9yZSwgaW4gdGVybXMgb2YgcG9wdWxhdGlvbiwgY2l0aWVzIGNhbiBiZSBzZXBlcmF0ZWQgaW50byB0aHJlZSBncm91cHMsIGBQZWFybCBSaXZlciBEZWx0YWAgYXJlYSBhbmQgYFRva3lvYCBhcmVhIGFyZSB0aGUgbW9zdCBnaWFudCBtZWdhY2l0aWVzIGluIEVhc3QgQXNpYS4gT3RoZXIgY2l0aWVzIGxpa2UgYEpha2FydGFgIGFyZWEgZnJvbSBJbmRvbmVzaWEsIGBTZW91bGAgYXJlYSBmcm9tIEtvcmVhLCBgTWFuaWxhYCBhcmVhIGZyb20gUGhpbGlwcG5lcywgYE9zYWthYCBhcmVhIGZyb20gSmFwYW4gYW5kIGBCZWlqaW5nYCBhcmVhIGZyb20gQ2hpbmEgY2FuIGJlIGNvbnNpZGVyZWQgYXMgc2Vjb25kIGdyb3Vwcy4gVGhlIHBvcHVsYXRpb24gb2YgcmVzdCBvZiB1cmJhbiBhcmVhcyBhcmUgd2l0aGluIGEgcmVsYXRpdmx5IHNpbWlsYXIgcmFuZ2UuCgohW1Nsb3BlM10oc2xvcGUzLnBuZykKCiogYEZpbmRpbmcyYCBXaGVuIHdlIHNlbGVjdCB0aGUgYFBvcHVsYXRpb24gRGVuc2l0eWAgbWVhc3VyZSwgd2UgY2FuIGNvbmNsdWRlIHRoYXQgdGhlIGBwb3B1bGF0aW9uIGRlbnNpdHlgIG9mIG1vc3QgdXJiYW4gYXJlYSBoYXZlIGluY3JlYXNlZCB3aXRoaW4gdGhlc2UgdGVuIHllYXJzIGFuZCB0aGUgb3Zlci1wb3B1bGF0aW9uIHByb2JsZW0gaXMgZXZlbiB3b3JzZSBpbiAyMDEwIHRoYW4gaW4gMjAwMC4gSG93ZXZlciwgYXMgdGhlIG9uZSBvZiB0aGUgbW9zdCBjcm93ZWQgYXJlYSBpbiB0aGUgd29ybGQsIGBIb25na29uZ2AgaGFzIGJlZW4gZGVhbGluZyB3aXRoIG92ZXItcG9wdWxhdGlvbiBwcm9ibGVtIGZvciBhIGNlbnR1cnkuIEZvcnR1bmVseSwgdGhlcmUgaXMgYSBzbGlnaHRseSBkZWNyZWFzZSBvZiBgcG9wdWxhdGlvbiBkZW5zaXR5YCBpbiBgSG9uZ0tvbmdgIGZyb20gMzMuMjMgdG8gMzIuMTMuCgoKKiBgRmluZGluZzNgIFRoZSBjcm93ZGVkIGFyZWEgcHJvYmxlbSBpcyBtb3JlIHNldmVyIGluIG90aGVyIEFzaWFuIGNvdW50cmllcyB0aGFuIENoaW5hIHdoaWNoIGhhcyBhIGxhcmdlIGFtb3VudCBvZiB1cmJhbiBhcmVhcy4gRm9yIGV4YW1wbGUsIGZvciBjb3VudHJpZXMgbGlrZSBJbmRvbmVzaWEsIFZpZXRuYW0gYW5kIFBoaWxpcHBuZXMsIHRoZXJlIGFyZSBzZXZlcmFsIHVyYmFuIGFyZWFzIHdpdGggYHBvcHVsYXRpb24gZGVuc2l0eWAgbGFyZ2VyIHRoYW4gMjAuIE9uIHRoZSBjb3VudHJhcnksIGZvciBtb3N0IHVyYmFuIGFyZWFzIGluIENoaW5hLCBgcG9wdWxhdGlvbiBkZW5zaXRpZXNgIGFyZSBwcmV0dHkgbG93LiBUaGVyZWZvcmUsIGZvciBhcmVhcyB3aXRoIGhpZ2ggYHBvcHVsYXRpb24gZGVuc2l0eWAsIHRoZSBob3VzaW5nIHNob3J0YWdlIG1heSBiZSBhIGNyaXRpY2FsIGlzc3VlLiBIb3dldmVyLCBsb3cgYHBvcHVsYXRpb24gZGVuc2l0eWAgZG9lcyBub3QgbWVhbiBvdmVyLXBvcHVsYXRpb24gaXMgbm90IGEgYmlnIGlzc3VlIGZvciB1cmJhbiBhcmVhcyBzaW5jZSBvdmVyY29taW5nIHRoZSBvdmVyLXBvcHVsYXRpb24gcHJvYmxlbSBhbmQgcmVhc29uYWJseSBtYWtlIHRoZSByZXNvdXJjZSBhcnJhbmdlbWVudCBpcyBvbmUgb2YgdGhlIG1vc3QgZGlmZmljdWx0IHRhc2tzIGZvciBsb2NhbCBnb3Zlcm5tZW50cy4KCiFbU2xvcGUxXShzbG9wZTEucG5nKQoKKiBgRmluZGluZzRgIENvbnNpZGVyaW5nIHRoZSBgbGFuZCBhcmVhc2AsIGxhcmdlIGZhbW91cyB1cmJhbiBhcmVhcyBqdW1wIGludG8gb3VyIHZpZXcgc3VjaCBhcyBgUGVhcmwgUml2ZXIgRGVsdGFgICwgYFRva3lvYCwgYFNoYW5naGFpYCBhbmQgYEJlaWppbmdgLiBXZSBjYW4gYWxzbyBub3RpY2UgdGhhdCB0aGVyZSBpcyBzdGlsbCBhIGh1Z2UgaW5jcmVhc2Ugb2YgbGFuZCBhcmVhcyBmb3IgY2l0aWVzIGluIENoaW5hIGJ1dCBpdCBpcyBub3QgdGhlIHNpdHVhdGlvbiBpbiBgVG9reW9gLiBPbmUgb2YgdGhlIHJlYXNvbnMgYmVoaW5kIHRoaXMgcGhlbm9tZW5vbiBwb3NzaWJseSBiZSB0aGUgbGltaXRhdGlvbiBvZiBjb3VudHJ5IHNpemUgb2YgSmFwYW4gYW5kIHRoZSB0cmVtZW5kb3VzIGxhbmQgYXJlYXMgb2YgQ2hpbmEuIEFub3RoZXIgcmVhc29uIGNvdWxkIGJlIHRoZSBhY3R1YWwgZWNvbm9taWMgc2l0dWF0aW9uIG9mIHRoZXNlIGFyZWFzIHNpbmNlIGBQZWFybCBSaXZlciBEZWx0YWAsIGBTaGFuZ2hhaWAgYW5kIGBCZWlqaW5nYCBhcmUgdGhlIG1vc3QgYWR2YW5jZWQgYXJlYXMgaW4gQ2hpbmEgd2l0aCB0aGUgbGFyZ2VzdCBlY29ub21pYyBlZmZlY3RzIG9uIHRoZSB3aG9sZSBjb3VudHJ5LiBUaGVyZWZvcmUsIGl0IGlzIGNvbW1vbiBmb3IgdGhlc2UgdGhyZWUgY2l0aWVzIHRvIGF0dHJhY3QgbW9yZSBwZW9wbGUgdG8gd29yayBhbmQgbGl2ZSB0aGVyZSBhbmQgZW5sYXJnZSB0aGUgd2hvbGUgYXJlYS4KCiFbU2xvcGU0XShzbG9wZTQucG5nKQoKKiBgRmluZGluZzVgIElmIHdlIGFkanVzdCB0aGUgYGNvbXBhcmlzaW9uIG1lYXN1cmVgIGFuZCBgQm91bmRhcnkgVHlwZWAsIHdlIGNhbiBlYXNpbHkgZGV0ZWN0IHRoYXQgYENvbnRhaW5lZGAgYm91bmRhcnkgdHlwZSBkb21pbmF0ZXMgdGhlIHdob2xlIGRhdGFzZXQgYWNyb3NzIGBjb21wYXJzaW9uIG1lYXN1cmVgLiBTcGVjaWZpY2FsbHksIHVyYmFuIGFyZWFzIHdpdGggaGlnaCBgcG9wdWxhdGlvbmAsIGBwb3B1bGF0aW9uIGRlbnNpdHlgIG9yIGBsYW5kIGFyZWFgIGFyZSBtb3N0bHkgY2F0ZWdvcml6ZWQgaW50byBgY29udGFpbmVkYCBib3VuZGFyeSB0eXBlLgoKIyMjIEhlYXRtYXBzCgpJbiBvcmRlciB0byBjb21wYXJlIHRoZSBkZWdyZWUgb2YgZGlmZmVyZW5jZSBvZiBhbGwgdGhlIG51bWVyaWNhbCBmZWF0dXJlcywgd2UgaW5jbHVkZWQgYSBgSGVhdG1hcGAgaW4gb3VyIHNoaW55IGFwcCBzbyB3ZSBjYW4gbG9vayBhdCBzb21lIHN0YXRpc3RpYyBzdW1tYXJpZXMgb2YgdGhlIG51bWVyaWNhbCBmZWF0dXJlcyBpbiB0ZXJtcyBvZiBgYm91bmRhcnkgdHlwZWAuIFRoZSByb3dzIG9mIG91ciBoZWF0bWFwcyBhcmUgYENvdW50cmllc2AgYW5kIHRoZSBjb2x1bW5zIG9mIHRoZSBoZWF0bWFwcyBhcmUgZm9sbG93aW5nIHN0YXRpc3RpY2FsIHN1bW1hcnkgb2YgZWFjaCB2YXJpYWJsZTogYG1lYW5gLCBgbWVkaWFuYCwgYHNkYCBhbmQgYEJvdW5kYXJ5IFR5cGVgLiBUaGUgY29sb3Igb2YgbGVmdCB0aHJlZSBjb2x1bW5zIGlzIGRldGVybWluZWQgYnkgdGhlIHZhbHVlIG9mIGVhY2ggY2VsbHMgYW5kIHRoZSBjb2xvciBvZiByaWdodCB0aHJlZSBjb2x1bW5zIHdoaWNoIGFyZSBgQm91bmRhcnkgVHlwZWAgaXMgZGV0ZXJtaW5lZCBieSB0aGUgYG1lYXN1cmVgIHRoYXQgdGhlIHZpZXdlciBjaG9zZSBhdCB0aGUgcmlnaHQgdG9wIG9mIHRoZSBwYWdlCgpXaGlsZSBjcmVhdGluZyB0aGUgZGF0YSBtYXRyaXgsIHdlIG5lZWQgZ3JvdXAgdGhlIHZhcmlhYmxlIHdlIG5lZWQgYnkgY291bnRyeSBhbmQgc3VtbXJpc2UgdGhlIHZhcmlhYmxlIGludG8gbWV0cmljcyB0aGF0IHdlIGFzay4gQXQgdGhlIGVuZCwgd2UgbmVlZCB0byBjb25jYXRlbmF0ZSB0aGlzIGRhdGFmcmFtZSB3aXRoIGJvdW5kYXJ5IHR5cGUgZGF0YWZyYW0gaW50byB0aGUgZmluYWwgZGF0YWZyb21lLCBhbmQgdGhlbiB3ZSBjaGFuZ2UgdGhlIGRhdGF0eXBlIGludG8gbWF0cml4IGFuZCBwdXQgdGhlIG1hdHJpeCBpbnRvIHRoZSBgaGVhdG1hcC4yYCBmdW5jdGlvbiB0byBkcmF3IHRoZSBoZWF0bWFwLiBJbXBvcnRhbnRseSwgaW4gb3JkZXIgdG8gbGFiZWwgZWFjaCByb3cgd2l0aCBjb3VudHJ5IG5hbWUsIHdlIGhhdmUgdG8gY2xhcmlmeSB0aGUgcm93IG5hbWVzIGZvciB0aGUgZGF0YWZyYW1lIGFuZCB0aGUgbWF0cml4IHdpbGwga2VlcCB0aGlzIGF0dHJpYnV0ZS4KCiFbSGVhdG1hcDFdKGhlYXRfbGFuZF8xMC5wbmcpCgoqIGBGaW5kaW5nMWAgV2hlbiB3ZSBsb29rIGF0IHRoZSBgdXJiYW4gbGFuZGAgbm8gbWF0dGVyIGluIDIwMDAgb3IgMjAxMCwgd2UgY2FuIGZpbmQgdGhhdCBzb21lIGNvdW50cmllcyBoYXZlIG91dHN0YW5kaW5nIGBtZWRpYW5gIGFuZCBgbWVhbmAgdmFsdWVzIHN1Y2ggYXMgYFNpbmdhcG9yZWAgYW5kIGBNb25nb2xpYWAsIHdoaWNoIGlzIG5vcm1hbCwgc2luY2UgZm9yIHRoZXNlIHR3byBjb3VudHJpZXMsIHRoZXkgb25seSBoYXZlIG9uZSBtYWpvciB1cmJhbiBhcmVhIHJlc3BlY3RpdmVseS4gQWx0aG91Z2ggb3RoZXIgY291bnRyaWVzIGxpa2UgYENoaW5hYCBoYXMgbW9yZSB1cmJhbiBhcmVhcywgdGhlaXIgbGFuZCBhcmVhcyBhcmUgbm90IGNvbnNpc3Rlbmx5IGxhcmdlLgoKIVtIZWF0bWFwMl0oaGVhdF9wb3BfMDAucG5nKQoKKiBgRmluZGluZzJgIElmIHdlIHRha2UgYSBsb29rIGF0IHRoZSBgVXJiYW4gUG9wdWxhdGlvbmAgcGFpcmVkIHZhcmlhYmxlcyBpbiAyMDAwIGFuZCAyMDEwLCB0aGUgY29tcGFyYXNpb24gZm9sbG93cyB0aGUgc2FtZSBwYXR0ZXJuIGFzIHRoZSBgRmluZGluZzFgLiBTb21lIGNvdW50cmllcyBoYXZlIGhpZ2hlciBtZWFuIGFuZCBtZWRpYW4gdmFsdWVzIHN1Y2ggYXMgYFNpbmdhcG9yZWAsIGBNb25nb2xpYWAgcGx1cyBDYW1ib2RpYSB0aGFuIHJlc3Qgb2YgY291bnRyaWVzLiBJbnRlcmVzdGluZ2x5LCBmb3Igc29tZSBjb3VudHJpZXMgbGlrZSBgTm9ydGggS29yZWFuYCwgYFBhcHVhIE5ldyBHdWluZWFgLCBgTGFvc2AsIGBCcnVuZWlgIGFuZCBgVGltb3ItTGVzdGVgLCB0aGUgc21hbGxlciBtZWFuIGFuZCBtZWRpYW4gdmFsdWUgbWF5IGJlIGRlY2lkZWQgYnkgdGhlIHRvdGFsIHBvcHVsYXRpb24gb2YgdGhlIHdob2xlIGNvdXRyeSBvciBzb21lIHBvc3NpYmxlIHBvbGl0aWNhbCByZWFzb25zLgoKIVtIZWF0bWFwM10oaGVhdF9kZW5zaXR5XzAwLnBuZykKCiogYEZpbmRpbmczYCBUaGUgZGlzdHJpYnV0aW9uIG9mIGBwb3B1bGF0aW9uIGRlbnNpdHlgIGlzIGV2ZW4gbW9yZSBpbnRlcmVzdGluZyBpbiB0ZXJtcyBvZiBhYm92ZSB0d28gYEZpbmRpbmdzYCB0aGFuIGxvb2tpbmcgYXQgYWxvbmUuIFRha2UgTm9ydGggS29yZWFuIGFzIGFuIGV4YW1wbGUsIGl0IGhhcyBhIGhpZ2ggYHBvcHVsYXRpb24gZGVuc2l0eWAgaW4gYm90aCAyMDAwIGFuZCAyMDEwIGJ1dCBzbWFsbCB2YWx1ZXMgaW4gbWV0cmljcyBvZiBgVXJiYW4gUG9wdWxhdGlvbmAgYW5kIGB1cmJhbiBsYW5kYC4gSXQgcmVmbGVjdHMgdGhhdCB0aGUgYHBvcHVsYXRpb24gZGVuc2l0eWAgaXNzdWUgaXMgbW9yZSBjcml0aWNhbCBpc3N1ZSBmb3IgdGhlIGNlbnR1YWwgZ292ZXJubWVudCBpbiBjb3VudHJpZXMgd2l0aCBmZXcgdXJiYW4gYXJlYXMgdGhhbiBvdGhlciBjb3VudHJpZXMuIEluIG9yZGVyIHRvIHZlcmlmeSB0aGUgY29uY2x1c2lvbiwgd2UgY2FuIGxvb2sgYmFjayB0byBvdXIgYFNsb3BlIFBsb3RgIGFuZCB3ZSBjYW5ub3QgZmluZCB0aGUgYXJlYXMgb2YgTm9ydGggS29yZWEgZnJvbSB0aGUgdG9wIG9mIGBTbG9wZSBQbG90YC4gRnJvbSB0aGUgc29jaWFsIHNjaWVudGlzdCBwZXJzcGVjdGl2ZSwgd2UgbWF5IHJlYXNvbmFibHkgaHlwb3RoZWlzIHRoYXQgY291bnRyaWVzIGxpa2UgYE5vcnRoIEtvcmVhYCBtYXkgbm90IGhhdmUgc3VmZnVjaWVudCBleHBlcmllbmNlIGRlYWxpbmcgd2l0aCBoaWdoIGBwb3B1bGF0aW9uIGRlbnNpdHlgIGlzc3VlLgoKIyMjIE90aGVyIFBsb3RzCgojIyMjIERvdCBQbG90CgpJbiBvcmRlciB0byBzaG93IHRoZSBkaXN0cmlidXRpb24gb2YgaW5jcmVhc2UgcmF0ZSBvZiBwb3B1bGF0aW9uLCB3ZSBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBjb2x1bW5zIGZvciB0aGUgZXhpc3RlZCBkYXRhZnJhbWUgYnkgdXNpbmcgYG11dGF0ZWAgZnVuY3Rpb24gZnJvbSBgZHBseXJgIHRocm91Z2ggZGl2aW5nIHRoZSBwb3B1bGF0aW9uIGJ5IHRoZSBwb3B1bGF0aW9uIGluIDIwMDAgZm9yIGVhY2ggYXJlYS4gV2hhdCBpcyBtb3JlLCB3ZSBuZWVkIHRvIGNvbG9yIHRoZSBkb3RzLiBBdCB0aGUgYmVnYWlubmluZywgd2UgdHJpZWQgdG8gY29sb3IgZWFjaCBkb3QgYnkgdGhlIHBvcHVsYXRpb24gaW4gMjAxMCwgdW5mb3J0dW5hdGVseSwgdGhlcmUgaXMgbm8gaWRlbnRpY2FsIG51bWJlciBvZiBwb3B1bGF0aW9uIGZvciBlYWNoIGFyZWEsIHNvIHRoZSBjb2xvciBpcyBtZWFuaW5nbGVzcy4gVGhlbiwgd2Ugc3RhcnRlZCB0byBmYWN0b3IgdGhlIGRvdHMgaW50byBkaWZmZXJlbnQgZ3JvdXBzIGJ5IHRoZSBudW1iZXIgb2YgcG9wdWxhdGlvbiBpbiAyMDEwLiBGaW5hbGx5LCB3ZSBmb3VuZCB0aGF0IDUwMEssIDEgbWlsbGlvbiwgNSBtaWxsaW9uIGFyZSB0aGUgbW9zdCBhcHByb3ByaWF0ZSBicmVhayBwb2ludHMgdG8gZGlzdGluY3QgZGlmZmVyZW50IGRvdHMuIFdlIGFsc28gdmVyaWZ5IG91ciBncm91cGluZyBzdGF0ZWd5IHRocm91Z2ggYSBzY2llbnRpZmljIHJlc2VhcmNoIGFib3V0IGRlZmluaW5nIHRoZSBzaXplIG9mIGNpdGllcyBmcm9tIGEgaW5zdGl0dXRlIGluIENoaW5hLiBUaGUgY29sb3Igc2NoZW1lcyBvZiB0aGUgbGFuZCBkb3QgcGxvdCBhbmQgcG9wdWxhdGlvbiBkZW5zaXR5IGRvdCBwbG90IGFyZSBhbHNvIGZvbGxvd2luZyB0aGUgc2FtZSBzdHJhdGVneSB3aGljaCBoYXMgcHJvdmVkIHZlcnkgbWVhbmluZ2Z1bCBhbmQgZWZmZWN0aXZlIHRvIGRldGVjdCByaWNoIGluZm9ybWF0aW9uIHRocm91Z2ggZG90IHBsb3RzLgoKIVtEb3RwbG90Ml0oZG90X2xhbmQucG5nKQoKKiBgRmluZGluZzFgIFdoZW4gd2UgY2hvb3NlIGBMYW5kYCBhcyBtZWFzdXJlLCB3ZSBjYW4gbG9vayBhdCB0aGUgcmF0ZSBvZiBpbmNyZWFzZSBvZiBsYW5kIGZvciBlYWNoIHVyYmFuIGFyZWEgY29sb3JlZCBieSB0aGUgbGFuZCBhcmVhLiBJbiBvcmRlciB0byBtYWtlIHRoaXMgcGxvdCwgd2UgYG11dGF0ZWAgdHdvIG5ldyBjb2x1bW5zIGNhbGxlZCBgbGFuZF9pbmNyZWFzZWAgYW5kIGBsYW5kX2ZhY3RvcmAsIHdoaWNoIHJlcHJlc2VudGVzIHRoZSBpbmNyZWFzZSBvZiBsYW5kIG9mIGVhY2ggdXJiYW4gYXJlYSBhbmQgZmFjdG9yaXplIHRoZSBsYW5kIGFyZWEgaW50byA1IGxldmVscy4gVGhlbiwgdGhlIGRvdCBwbG90IGNhbiBiZSBjcmVhdGVkIGJ5IGNvdW50aW5nIHRoZSBudW1iZXIgb2YgZWFjaCBpbmNyZWFzZSByYXRlIGFuZCBjb2xvciB0aGUgZG90cyBieSB0aGUgYGxhbmRfZmFjdG9yYCBsZXZlbHMuIExpa2Ugb3VyIGV4cGVjdGF0aW9ucywgZm9yIGV4aXN0ZWQgdXJiYW4gYXJlYXMgd2l0aCBsYXJnZSBsYW5kLCBpdCBpcyBub3QgY29tbW9uIHRoYXQgdGhleSB3aWxsIGluY3JlYXNlIGEgbG90IG9mIHRoZSBsYW5kIGFyZWEsIGJ1dCB0aGVyZSBwcm9iYWJseSBhIGh1Z2UgaW5jcmVhc2UgZm9yIHNtYWxsIGxhbmQgdXJiYW4gYXJlYS4gSW50ZXJlc3RpbmdseSwgd2UgZm91bmQgdGhhdCB0aGVyZSBhcmUgc2V2ZXJhbCBodWdlIGxhbmQgYXJlYXMgaGF2aW5nIHNpZ25pZmljYW50bHkgaW5jcmVhc2UgaW4gdGhlIGxhbmQuIEltcG9ydGFudGx5LCBncm93dGggbWF5IGxlYWQgdG8gZWNvbm9taWMgb3Bwb3J0dW5pdGllcy4gSG93ZXZlciwgdGhpcyBzaXR1YXRpb24gYWxzbyBmb3JjZSBwb2xpY3kgbWFrZXJzIHRvIHRoaW5rIHRoZSBkZXNpZ24gb2YgY2l0aWVzIGNhcmVmdWxseSBzaW5jZSB0aGUgYXJyYW5nZW1lbnQgb2YgaW5mcmFzdHJ1Y3R1cmUgaGFzIGFscmVhZHkgYmVlbiBhIGNydWNpYWwgZGVjaXNpb24uIFdoaWxlIGNvbnNpZGVyaW5nIHRoZSBwYXJ0aWN1bGFyIHNpdHVhdGlvbiBmb3IgZWFjaCBjaXR5LCB0aGV5IGhhdmUgdGhlaXIgb3duIGNoYWxsZW5nZXMgYW5kIG9wcG9ydHVuaXRpZXMgaW4gZGlmZmVyZW50IHdheXMuCgohW0RvdHBsb3QxXShkb3RfcG9wLnBuZykKCiogYEZpbmRpbmcyYCBXaGVuIHdlIGNvbnNpZGVyIGBQb3B1bGF0aW9uYCBhcyBtZWFzdXJlLCB3ZSBjYW4gZ2V0IGEgY2xlYXIgdmlldyBhYm91dCB0aGUgZ3Jvd3RoIG9mIHVyYmFuIHBvcHVsYXRpb24uIFRoZSBmaXJzdCB2aWV3IHdlIGNhbiBnZXQgaXMgbWFueSBjaXRpZXMgaGF2ZSBzZWVuIGFuIGVub3Jtb3VzIGdyb3d0aCBpbiB0aGVpciBwb3B1bGF0aW9uIGJldHdlZW4gMjAwMCBhbmQgMjAxMC4gVGhlcmUgYXJlIGRlZmluaXRlbHkgb3V0bGllcnMgaWYgd2UgY29uc2lkZXIgdGhlIGdyb3d0aCBpbiBhIGNlcnRhaW4gcmFuZ2Ugc2luY2Ugd2UgY2FuIGRldGVjdCB0aGF0IHRoZXJlIGFyZSBzZXZlcmFsIGFyZWFzIGhhdmluZyBwb3B1bGF0aW9uIGdyb3d0aCByYXRlIG1vcmUgdGhhbiAxNTAlLgoKIVtEb3RwbG90M10oZG90X2RlbnNpdHkucG5nKQoKKiBgRmluZGluZzNgIElmIHdlIGxvb2sgYXQgdGhlIGBQb3B1bGF0aW9uIERlbnNpdHlgLCB0aGVyZSBhcmUgYm90aCBsYXJnZSBpbmNyZWFzZSBhbmQgZGVjbGluZS4gSW1wb3RhbnRseSwgaWYgd2UgdGFrZSBhIGxvb2sgYXQgdGhlIGBEYXRhIEV4cGxvcmVyYCBwYXJ0LCB3ZSBjYW4gZmluZCB0aGF0IG1ham9yaXR5IG9mIENoaW5lc2UgY2l0aWVzIGhhdmUgYSBkZW5zaXR5IGRlY2xpbmUuIGluIG91ciBvcGluaW9ucywgdGhpcyBjb3VsZCBiZSBpbmZsdWVuY2VkIGJ5IHRoZSBwaGVub21lbm9uIG9mICdHaG9zdCBjaXRpZXMnIGFuZCByaXNpbmcgaW5jb21lcy4gRnVydGhlcm1vcmUsIHdlIGNhbiBmb2N1cyBvbiB0aGUgYXJlYXMgd2l0aCBoaWdoIGRlbnNpdHkgaW5jcmVhc2UgYW5kIHdlIGZpbmQgdGhhdCBsb3cgaW5jb21lIGNvdW50cmllcyBoYXZlIGEgY29tcGFyYXRpdmVseSBoaWdoIGdyb3d0aCBzaW5jZSBwZW9wbGUgdXN1YWxseSBtaWdyYXRlIGZyZWVseS4KCiMjIyMgSGlzdG9ncmFtCgohW0hpc3RvZ3JhbTNdKGhpc3RfY291bnRyeS5wbmcpCgoqIGBGaW5kaW5nMWAgaGlzdG9ncmFtIG9mIHRoZSBjYXRhZ29yaWNhbCB2YXJpYWJsZSBgQ291bnRyeWAgc2hvd3MgdGhlIG51bWJlciBvZiB1cmJhbiBhcmVhcyB0aGF0IGFwcGVhciBpbiB0aGUgZGF0YS5UaGUgdmFyaWFibGUgYENvdW50cnlgIGlzIHZlcnkgaW1wb3J0YW50IGZvciBvdXIgYW5hbHlzaXMgaW4gcHJvamVjdC4gU2luY2UgZGlmZmVyZW50IGNvdW50cmllcyB2YXJ5IGluIGFzcGVjdHMgc3VjaCBhcyBwb3B1bGF0aW9uLCBsYW5kIGFyZWEsIGVjb25vbWljIGRldmVsb3BtZW50IGxldmVscywgdGhlIGxldmVscyBvZiB0aGVpciB1cmJhbml6YXRpb24gYXJlIGFsc28gZGlmZmVyZW50IGZyb20gZWFjaCBvdGhlci4gVGhlIHBsb3QgcHJvdmlkZXMgdXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiB1cmJhbiBhcmVhcyBhbmQgYSBnZW5lcmFsIGlkZWEgb2YgdGhlIHNjYWxlIG9mIF9wb3B1bGF0aW9uXyBhbmQgX2xhbmQgYXJlYV8uIEl0IGlzIGNsZWFyIHRoYXQgYENoaW5hYCBkb21pbmF0ZXMgb3RoZXIgRWFzdGVybiBBc2lhbiBjb3VudHJpZXMgaW4gdGhlIG51bWJlciBvZiB1cmJhbiBhcmVhcyBieSBhIGxhcmdlIG51bWJlciBvZiB1cmJhbiBhcmVhcy4gSW4gb3JkZXIgdG8gdmlzdWFsaXplIHRoZSBudW1iZXIgb2YgdXJiYW4gYXJlYXMgb2Ygb3RoZXIgY291bnRyaWVzIG1vcmUgZWZmaWNpZW50bHkgd2l0aCByZWFzb25hYmxlIHNjYWxpbmcsIHdlIGV4Y2x1ZGUgYENoaW5hYCBpbiB0aGUgbmV4dCBoaXN0b2dyYW0uCgohW0hpc3RvZ3JhbTFdKGhpc3RfbGFuZC5wbmcpCgoqIGBGaW5kaW5nMmAgaGlzdG9ncmFtIHNob3dzIHRoYXQgZnJvbSAyMDAwIHRvIDIwMTAgaW4gRWFzdCBBc2lhLCB1cmJhbiBsYW5kIHNpemUgaW5jcmVhc2VzIHdpdGggdXJiYW5pemF0aW9uLiBNb3N0IG9mIHVyYmFuIGFyZWFzIGRvIGhhdmUgdGhlaXIgdXJiYW4gbGFuZCBpbmNyZWFzZSBhdCB0aGUgYXZlcmFnZSBhbm51YWwgcmF0ZSBmcm9tIDAlIHRvIDUlLCBwcmVmZXJhYmx5IDAlLiBGZXcgdXJiYW4gYXJlYXMgaW5jcmVhc2UgYmV5b25kIGFubnVhbCByYXRlIG9mIDEwJS4gQnV0IG5vIHVyYmFuIGFyZWEgc2hyaW5rcyBkdXJpbmcgdXJiYW5pemF0aW9uLiBUaGlzIGluZGljYXRlcyB0aGF0IHRoZSBleHBhbmRpbmcgdXJiYW4gYXJlYXMgaXMgbmVjZXNzYXJ5IGZvciB1cmJhbml6YXRpb24gcHJvY2VzcyBldmVuIHRob3VnaCBhdCByZWxhdGl2ZWx5IGxvdyByYXRlLgoKIVtIaXN0b2dyYW0yXShoaXN0X3BvcC5wbmcpCgoqIGBGaW5kaW5nM2AgaGlzdG9ncmFtIHNob3dzIHRoYXQgZnJvbSAyMDAwIHRvIDIwMTAsIG1vc3Qgb2YgdGhlIHVyYmFuIGFyZWFzIGluIEVhc3QgQXNpYSBoYXZlIGluY3JlYXNlZCBpbiB1cmJhbiBwb3B1bGF0aW9uIHNpemUgd2hpbGUgZmV3IGhhdmUgZGVjcmVhc2VkIGluIHVyYmFuIHBvcHVsYXRpb24gc2l6ZS4gSW4gY29tbW9uIHNlbnNlLCB1bmRlcmdvaW5nIHVyYmFuaXphdGlvbiBzaG91bGQgaGF2ZSBpbmNyZWFzZSBpbiBpdHMgcG9wdWxhdGlvbi4gSG93ZXZlciwgb21wYXJlZCB0byBwcmV2aW91cyBoaXN0b2dyYW0gb2YgYXZlcmFnZSByYXRlIG9mIGluY3JlYXNlIGluIHVyYmFuIGxhbmQgdGhhdCBzaG93cyB0aGF0IHVyYmFuIGxhbmQgc2l6ZSBpbmNyZWFzZXMgaW4gdXJiYW5pemF0aW9uLCB0aGlzIGhpc3RvZ3JhbSBpbmRpY2F0ZXMgdGhhdCB3aXRoIGZldyB1cmJhbiBhcmVhcyBkZWNyZWFzZSBpbiB1cmJhbiBsYW4gc2l6ZSwgZXhwYW5zaW9uIG9mIHVyYmFuIHBvcHVsYXRpb24gaXMgbm90IG5lY2Vzc2FyeSBidXQgY29tbW9uIGluIHVyYmFuaXphdGlvbi4KCgojIyA2LiBDb25jbHVzaW9uCiogbGltaXRhdGlvbiBhbmQgZnV0dXJlIGRpcmVjdGlvbiAxOiB3ZSBvbmx5IGhhdmUgdGhlIGRhdGEgZm9yIHRoZSB5ZWFyIG9mIDIwMDAgYW5kIDIwMTAgaW5zdGVhZCBvZiBoYXZpbmcgdGhlIGRhdGEgZm9yIHRoZSAxMCB5ZWFycy4gSW4gdGhpcyBjYXNlLCB3ZSBjYW4gb25seSBzZWUgdGhlIGp1bXAgb2YgZGF0YSBmcm9tIDIwMDAgdG8gMjAxMC4gQnV0IHdlIGFyZSB1bmFibGUgdG8gc2VlIHRoZSBwcm9jZXNzIG9mIGNoYW5nZSBkdXJpbmcgdGhpcyBkZWNhZGUuIEZvciBleGFtcGxlLCBpbiB0aGUgeWVhciBvZiAyMDA4IHdoZW4gdGhlIGdsb2JhbCBmaW5hbmNpYWwgY3Jpc2lzIG9jY3VyZWQsIHRoZXJlIG11c3QgaGF2ZSBiZWVuIGEgZ3JlYXQgaW1wYWN0IG9uIHVyYmFuaXphdGlvbi4gSWYgd2UgaGF2ZSBzdWNoIGRhdGEgZm9yIDEwIHllYXJzLCB3ZSBjYW4gdmlzdWFsaXplIHRoZSBjaGFuZ2Ugb2YgZWFjaCB2YXJpYWJsZSBhcyBhIHRpbWUgc2VyaWVzIGFuZCBpbnZlc3RpZ2F0ZSB0aG9zZSBjaGFuZ2VzIGluZGl2aWRhdWxseS4gCgoqIGxpbWl0YXRpb24gYW5kIGZ1dHVyZSBkaXJlY3Rpb24gMjogZm9yIG91ciBzbG9wZSBwbG90IGZvciBpZGVudGljYWwgdmFyaWFibGVzIGluIDIwMDAgYW5kIDIwMTAsIHdlIGNhbiBvbmx5IHZpc3VhbGl6ZSB0aGUgc2xvcGUgbGluZXMgb2YgdG9wIHVyYmFuIGFyZWFzIHRoYXQgaGF2ZSBsYXJnZSB2YWx1ZXMgYW5kIHRoZSBzbG9wZSBsaW5lcyBvZiBtb3N0IHVyYmFuIGFyZWFzIGFyZSBjb25kZW5zZWQgYXQgdGhlIGJvdHRvbSBhbmQgaXQgaXMgaGFyZCB0byB0ZWxsIHRoZSBzbG9wZS4gVG8gc29sdmUgdGhpcywgaXQgbWlnaHQgYmUgaGVscGZ1bCB0byBncm91cCB0aG9zZSB1cmJhbiBhcmVhcyBhbmQgdmlzdWFsaXplIHNlcGVyYXRlbHkuCgpDb2RlIGxpbms6IGh0dHBzOi8vZ2l0aHViLmNvbS96YW5nY2MwNDc0L0VEQV9GaW5hbC5naXQKClNoaW55IHZpc3VhbGl6YXRpb24gbGluazogaHR0cHM6Ly9tZWthLnNoaW55YXBwcy5pby9lZGFfcHJvamVjdC8j